Académique Documents
Professionnel Documents
Culture Documents
(POO) en C++
POLYMORPHISME
EN C++
INTRODUCTION
- Une classe dérivée peut fournir une nouvelle définition d’une méthode d'une
classe parent car elle peut avoir besoin de réagir différemment à l'appel de cette
méthode. Cette redéfinition substituera une méthode à une autre : c’est la
spécialisation.
- La notion de polymorphisme signifie que, la même opération pouvant se
comporter différemment sur différentes classes de la hiérarchie, il est possible
d'appeler la méthode d'un objet sans se soucier de son type intrinsèque.
- Dans l’exemple des classes Etudiant et Enseignant qui dérivent de la classe
Personne, la fonction affiche n’est pas la même pour une personne, un Etudiant ou
un Enseignant. La redéfinition de cette fonction dans chacune des sous-classes
adaptera un comportement différent suivant que la Personne est Etudiant ou
Enseignant.
POLYMORPHISME : INTRODUCTION
Le polymorphisme : «Poly» signifie «plusieurs» et «morphe» signifie «forme».
Ceci correspond à du code fonctionnant de différentes manières selon le type
qui l'utilise.
La norme ANSI du C++ offre un mécanisme permettant d'identifier, lors de l'exécution, le
type d'une variable, d'une expression ou d'un objet. En particulier, il est possible de
connaître le véritable type d'un objet désigné par un pointeur ou une référence.
● L'opérateur qui permet cela est : typeid
● Cet opérateur renvoie un résultat de classe : type_info
● La classe type_info fournit une méthode name() qui renvoie le type sous la forme d'une
chaîne de caractère (char* )
Les opérateurs == et != permettent de comparer deux objets de la classe type_info.
. LA RÉSOLUTION DE LIENS
void acquisition(Personne p)
{ p.saisie();
p.affiche();
}
Dans main(), utilisont cette fonction pour une Personne x et un Etudiant e :
main()
{ Personne x;
Etudiant e;
acquisition(x); // OK
acquisition(e); // ici, l’objet e perd sa vraie nature dans la fonction
// et sera considéré comme une Personne, donc ce sont
// les méthodes de la classe Personne qui seront
// appelées et non celle de la classe Etudiant.
}
=> C’est le type de l’objet qui détermine quelle fonction
membre appeler et non sa vraie nature.
- La résolution dynamique des liens
Pour faire appel aux méthodes membres en se basant sur la vraie nature
de l’objet, il faut :
→ utiliser des pointeurs ou références sur les objets
→ déclarer les méthodes virtuelles (elles deviennent alors polymorphiques)
class Personne {
….
virtual void affiche();
virtual void saisie();
...
}
void acquisition(Personne &p) // ou bien Personne* p
{ p.saisie();
p.affiche();
}
main()
{ Personne x;
Etudiant e;
acquisition(x);
acquisition(e); // pour un objet e de la classe Etudiant, c’est
//fonctions membres de sa classe qui seront appelées.
}
→ Il n’est pas nécessaire de déclarer les fonctions virtuelles dans les classes
filles, mais il est nécessaire de les définir.
→ Un constructeur ne doit pas être virtuel, à la construction des objets, on
sait toujours ce que l’on construit.
→ Pour le destructeur, il est impératif d’appeler le bon destructeur, donc il
faut rendre le destructeur virtuel si on utilise le polymorphisme:
virtual ~Personne();
. FONCTIONS VIRTUELLES PURES
Il peut arriver que la méthode des classes filles que l’on veut déclarer
virtuelle n’ait aucune signification dans la classe mère → donc pas de
code à écrire (fonction ne voulant rien dire dans le cas de la classe mère).
Dans ce cas, il faut comme même la déclarer virtuelle dans la classe mère
comme suit :
virtual int fonction() const = 0; //elle est alors une fonction virtuelle pure.
CLASSES ABSTRAITES
Une classe possédant au moins une méthode (fonction) virtuelle pure est
abstraite.
On ne peut pas créer d’instance d’une classe abstraite.