Previous Next Contents




Polymorphisme : sommaire


Polymorphisme  1


Polymorphisme






Le polymorphisme désigne la faculté de prendre plusieurs formes.






Deux expressions du polymorphisme :





Polymorphisme  2


Polymorphisme statique


Polymorphisme  3


Polymorphisme dynamique (1)


Polymorphisme  4


Polymorphisme dynamique (2)







figure *f;
// ...
switch(...) {
   case ... :
      f = new rectangle; break;
   case ... :
      f = new carre; break;
   case ... :
      f = new hexagone; break;
}
f->afficher();
// On voudrait appeler la bonne version
// de afficher selon la valeur de f
// Actuellement : appel de
//             figure::afficher() !!!
// .... transformer afficher
// en fonction virtuelle


Polymorphisme  5


Méthode virtuelle (1)

class figure { ...
public:
   virtual void afficher(void) const;
};
class rectangle : public figure { ...
public:
   virtual void afficher(void) const;
};
rectangle r;
figure *ptf=&r;
ptf->afficher() ; // rectangle::afficher()
figure& rf=r;
rf.afficher(); //rectangle::afficher()
La détermination de la méthode à appeler est effectuée dynamiquement selon le type effectif de l'objet pointé ou référé (on parle de liaison dynamique).


Polymorphisme  6


Méthode virtuelle (2)


Polymorphisme  7


Méthode virtuelle (3)

class A {
public :
   virtual void foo() { cout << "A"; } ;
};
class B : public A {
public:
// foo reste virtuelle
   void foo() { cout << "B"; } ;
};
class C : public B {
public:
// foo reste virtuelle
   void foo() {cout << "C"; };
};
int main() {
   A * a = new C;
   B * b = new C;
   a->foo(); // foo virtuelle --> C::foo()
   b->foo(); // foo virtuelle --> C::foo()


Polymorphisme  8


Table de fonctions virtuelles (1)

Le mécanisme de polymorphisme dynamique est réalisé par les tables de fonctions virtuelles :

Polymorphisme  9


Table de fonctions virtuelles (2)

class rectangle : public figure{
protected:
   int l,lg;
public:
   rectangle(int x=0, int y=0): l(x),lg(y){}
   virtual int perimetre(void) const ;
   int aire(void) const ;
};
class carre : public rectangle {
public:
   carre(int l=0) : rectangle(l,l) {}
   int perimetre(void) const ;
   int aire(void) const ;
};
int main() {
   rectangle * r = new rectangle(20,30);
   cout << r->perimetre() << endl;
   carre * c = new carre(10);
   r = c;
   cout << r->perimetre() << endl;
   cout << r->aire() << endl;
}


Polymorphisme  10


Tables de fonctions virtuelles (3)
rectangle * r;

r = new rectangle(20,30) ;
// mise en place du vptr adéquat -->






r->perimetre() ; // rectangle::perimetre

carre * c = new carre(10) ;
// mise en place du vptr adéquat
r = c;






r->perimetre() ; // carre::perimetre

r->aire(); // rectangle::aire résolu à la compilation
// ((carre *) r)->aire(); --> carre::aire


Polymorphisme  11


Destructeur virtuel

class Base { ...
};
class Deriv : public Base {
   int *pt ; ...
public:
   Deriv() { pt = new int[10]; }
   ~Deriv() { delete [] pt; }
   // ...
};
Base *ptB = new Deriv;
delete ptB;// a priori appel de ~Base()
// --> espace mémoire non libéré
Si une classe dérivée a un destructeur, déclarer le destructeur de la classe de base comme étant virtual

class Base {
   virtual ~Base(); //...
};


Polymorphisme  12


Méthode virtuelle et encapsulation


Polymorphisme  13


Fonction virtuelle pure


Polymorphisme  14




Classe abstraite

Polymorphisme  15


Liaison statique vs. liaison dynamique


Polymorphisme  16


Exemple : Tri d'objets (1)

class Sortable {
public:
   // retourne 0 si égaux
   virtual int compare(Sortable const &) const =0;
   virtual ~Sortable();
   virtual int getsignature() const =0;
};
class Personne : public Sortable {
protected:
   char nom[25];
   int salaire;
public:
   int compare(Sortable const &) const;
   int getsignature() const;
   ~ Personne();
   // ...
};


Polymorphisme  17


Exemple : Tri d'objets (2)

int Personne::getsignature() const {
   // identificateur propre aux personnes
   // static --> adresse de tag est unique
   static int tag;
   return (int &tag);
}
// retourne 0 si égaux
int Personne::compare(Sortable const & other) {
   register int cmp;
   // Vérif. comparaison de deux Personnes
   if ((cmp = getsignature()
         - other.getsignature()))
      return cmp;
   // conversion de Sortable en Personne
   Personne const & o = (Personne const&) other;
   if ((cmp = strcmp(nom,o.nom)) == 0)
      return cmp;
   return 1;
}




Previous Next Contents