Compilation & Directives de préprocesseur Pointeurs, Références & Allocation Dynamique de Mémoire Spécificités du C++ (indépendantes de la POO) Structures & Classes Encapsulation des données Constructeur & Destructeur de classe Copie d'objets Amitié & Surcharge d'opérateur Héritage (Partie 1) Héritage (Partie 2) Patrons de fonctions et de classes Introduction à la librairie standard
Retour menu principal

Héritage (Partie 2) : Méthodes virtuelles & Classes abstraites


Rappel sur l’héritage simple

 1: class polygone
 2: {
 3: public:
 4:   polygone(const unsigned int nbr_segment_);
 5: protected:
 6:   unsigned int m_nombre_segment;
 7: };
 8: 
 9: class rectangle : public polygone
10: {
11: public:
12:   rectangle(const double longueur_, const double largeur_);
13: private:
14:   double m_longueur;
15:   double m_largeur;
16: };

Rappel sur l’héritage simple

 1: polygone::polygone(const unsigned int nbr_segment_) :
 2:   m_nombre_segment(nbr_segment_)
 3: {
 4: }
 5: 
 6: rectangle::rectangle(const double longueur_, const double largeur_) :
 7:   polygone(4),
 8:   m_longueur(longueur_), m_largeur(largeur_)
 9: {
10: }

Liaisons statiques

Classe polygone

class polygone
{
public:
  void affiche() const;
  ...
};

Classe rectangle

class rectangle : public polygone
{
public:
  void affiche() const;
  ...
};

:BEAMER_ENV: ignoreheading

Programme principal

int main()
{
  polygone  my_polygone;
  rectangle my_rectangle;
  my_polygone.affiche();
  my_rectangle.affiche();
}

:BEAMER_ENV: ignoreheading

Comportement souhaité car le compilateur connait, lors de la compilation, le type d'objet instancié

Liaisons statiques

Classe polygone

class polygone
{
public:
  void affiche() const;
  ...
};

Classe rectangle

class rectangle : public polygone
{
public:
  void affiche() const;
  ...
};

:BEAMER_ENV: ignoreheading

Programme principal

int main()
{
  polygone  my_polygone;
  rectangle my_rectangle;
  my_polygone.affiche();
  my_rectangle.polygone::affiche();
}

Liaisons statiques

Classe polygone

class polygone
{
public:
  void affiche() const;
  ...
};

Classe rectangle

class rectangle : public polygone
{
public:
  void affiche() const;
  ...
};

:BEAMER_ENV: ignoreheading

Programme principal

int main()
{
  polygone * ptr_polygone1 = new polygone;
  polygone * ptr_polygone2 = new rectangle;
  ptr_polygone1->affiche();
  ptr_polygone2->affiche();
}

:BEAMER_ENV: ignoreheading

Comportement non souhaité car le compilateur ne connait pas, lors de la compilation, le type d'objet alloué : liaison statique

Liaisons dynamiques & Méthodes virtuelles

Classe polygone

class polygone
{
public:
  virtual void affiche() const;
  ...
};

Classe rectangle

class rectangle : public polygone
{
public:
  void affiche() const;
  ...
};

:BEAMER_ENV: ignoreheading

Programme principal

int main()
{
  polygone * ptr_polygone1 = new polygone;
  polygone * ptr_polygone2 = new rectangle;
  ptr_polygone1->affiche();
  ptr_polygone2->affiche();
}

:BEAMER_ENV: ignoreheading

L'utilisation d'une liaison dynamique via le mot-clé virtual indique au compilateur que le choix de la méthode ne s'effectuera qu'à l'exécution du code

Liaisons dynamiques & Méthodes virtuelles

Le processus de virtualisation permet ainsi de redéfinir des méthodes suivant la finalité de la classe fille

Classe polygone

class polygone
{
public:
  virtual void affiche() const;
  ...
};

void polygone::affiche() const
{
  cout << "Nombre de segment = "
       << m_nombre_segment << endl;

}

Classe rectangle

class rectangle : public polygone
{
public:
  void affiche() const;
  ...
};

void rectangle::affiche() const
{
  polygone::affiche();
  cout << "Longueur = " << m_longueur << endl;
       << "Largeur  = " << m_largeur << endl;
}

Classes abstraites

  • La notion de liaison dynamique permet de redéfinir une méthode au sein de classes filles : on parle de méthodes virtuelles
  • C++ permet la déclaration de méthodes virtuelles pures c’est-à-dire des méthodes dont la définition n'est pas donnée

Classes abstraites

Exemple du jeu d’échec :

  • La classe piece est par construction une classe abstraite : elle déclare des méthodes affiche(), deplacement() mais ne les définit pas
  • La définition n’intervient que dans les classes dérivées qui spécialisent les méthodes en fonction de leur besoin

Classes abstraites

Classes abstraites

#include "pion.h"
#include "tour.h"
int main()
{
  const size_t nbr_pieces = 2;
  piece * pieces[nbr_pieces];

  pieces[0] = new pion;
  pieces[1] = new tour;

  for (size_t i = 0; i < nbr_pieces; ++i)
  {
    pieces[i]->affiche();
  }
}

Étant donné le canevas fourni par la déclaration de la classe piece, libre à chacun de développer, de façon indépendante, sa propre implémentation de piece en définissant ces fonctionnalités