Lorsque la classe de base possède un constructeur par défaut, celui-ci est appelé automatiquement avant lappel du constructeur de la classe dérivée, pour initialiser les données membres de base. Il est cependant permis à un constructeur de la classe dérivée de faire un appel explicite à un constructeur de la classe de base, afin dinitialiser les membres hérités ; cet appel se fait de la même façon que pour les membres qui sont des classes (chapitre 5), cest-à-dire en plaçant derrière la liste des arguments le symbole :
puis le nom de la classe de base (qui est aussi celui de son constructeur) avec ses arguments. Voici donc comment définir de manière naturelle les deux constructeurs de la classe rectplein
:
rectplein::rectplein(){ // appel implicite de rectangle::rectangle(); couleur = 0;}rectplein::rectplein(int gche, int haut, int drte, int bas, int couleur) : rectangle(gche, haut, drte, bas) // explicite{ coul = couleur; trace();}
Le premier constructeur appelle en fait le constructeur par défaut de rectangle
(qui crée un rectangle vide), ce quil nest pas nécessaire de préciser. Par contre, dans le second, on souhaite utiliser lautre constructeur (qui crée un rectangle à partir de ses coordonnées), et il faut alors le mentionner explicitement.
Il résulte de ces règles que lorsquune classe na pas de constructeur par défaut, les classes dérivées doivent obligatoirement appeler un constructeur de la classe de base.
Le destructeur dune classe dérivée appelle le destructeur de la classe de base après lexécution de ses tâches explicites. Ainsi on peut écrire :
rectplein::~rectplein(){ efface(); // appel implicite de rectangle::~rectangle();}
Comme il ny a quun destructeur par classe, il ny a pas à choisir.
On retiendra que les constructeurs sont appelés dans lordre ascendant des classes (de base vers dérivées), tandis que les destructeurs le sont dans lordre inverse. Il sagit bien là dun ordre conforme à la logique. En effet, le constructeur dune classe dérivée peut avoir besoin des membres de la classe de base (cest le cas dans notre exemple, puisque la fonction trace
utilise les coordonnées du rectangle) : il en résulte que la partie de base de lobjet doit être initialisée avant quon ne commence la construction explicite. Inversement, le destructeur aussi peut avoir besoin des membres hérités : il ne faut donc pas les détruire en premier, mais seulement après.
![]() | ![]() | Suivant ![]() |