Les pointeurs dune classe de base sont compatibles avec ceux des classes dérivées :
rectangle *pr;rectplein rp, *prp = &rp;pr = prp; // autorisé
Il nest pas nécessaire de préciser un changement de type. Par contre, en sens inverse il faut le faire, et lopération est alors périlleuse, car lordinateur risque fort de se planter si lon fait un appel à une méthode de rectplein
avec un pointeur à qui lon a affecté une valeur rectangle*
. On sait de toute façon que les changements de types sur les pointeurs doivent être employés avec prudence.
Contrairement à laffectation dune instance de la classe dérivée vers la classe de base, qui fait perdre de linformation (les membres spécifiques à la classe dérivée sont perdus), laffectation identique avec les pointeurs ne fait rien perdre : les membres dérivés sont simplement momentanément inaccessibles. Les méthodes virtuelles de la classe de base sont cependant appelées correctement. Par exemple, si lon a défini un destructeur virtuel et deux méthodes virtuelles trace
et efface
, les appels suivants seront corrects :
rectangle r, *pr = new rectangle(r);pr->trace(); // appel de rectangle::tracedelete pr; // appel de rectangle::~rectanglepr = new rectplein();pr->trace(); // appel de rectplein::tracedelete pr; // appel de rectplein::~rectplein
Cela explique pourquoi lon parle de polymorphisme. On retiendra limportance quil y a à déclarer des destructeurs virtuels, même sils ne font rien : il nen sera pas forcément de même dans les classes dérivées, et le compilateur, comme lexemple ci-dessus le montre clairement, ne peut pas déterminer correctement sur quel genre dobjet pointe pr
, et donc quel destructeur appeler sil nest pas virtuel. Noter que pour la même raison, lappel de sizeof(*pr)
donnera toujours la taille de la classe de base rectangle
, même si pr
pointe sur un objet rectplein
. On se méfiera de cet opérateur qui ne peut de surcroît pas être redéfini.
Précédent | Sommaire | Suivant |