destructeurs virtuels et héritage
Le
Edrusb
Bonjour,
j'ai une question toute bête :
Pour simplifier j'ai trois classes qui dérivent les unes des autres (A
-> B -> C) les objets de chaque classe peuvent être manipulés (alloués,
détruits) par des pointeurs des classes parents, j'ai donc besoin de
destructeur virtuels.
Est-ce que chaque classe doit définir un destructeur virtuel ou est-ce
que définir un destructeur virtuel pour la classe A implique que les
destructeurs implicites ou explicites des classes héritées sont virtuels
aussi:
Soit à dire est-ce que ces déclarations :
class A
{
public:
virtuel ~A() {};
};
class B : public A
{
public:
// pas de destructeur explicite
// ou destructeur explicite sans mot clef "virtuel"
};
class C : public B
public:
// pas de destructeur explicite
// ou destructeur explicite sans mot clef "virtuel"
};
suffisent pour utiliser le code suivant sans risque de fuite mémoire:
B *ptr1;
B *ptr2;
ptr1 = new B;
ptr2 = new C;
delete ptr1;
delete ptr2;
ou bien dois-je obligatoirement déclarer les classes B et C comme ceci:
class B : public A
{
public:
virtual ~B(){/* implémentation éventuelle */};
};
class C : public B
public:
virtual ~C(){/* implémentation éventuelle */};
};
Merci d'avance pour toute réponse.
--
Edrusb
edrusba@free.fr (supprimer le 'a')
j'ai une question toute bête :
Pour simplifier j'ai trois classes qui dérivent les unes des autres (A
-> B -> C) les objets de chaque classe peuvent être manipulés (alloués,
détruits) par des pointeurs des classes parents, j'ai donc besoin de
destructeur virtuels.
Est-ce que chaque classe doit définir un destructeur virtuel ou est-ce
que définir un destructeur virtuel pour la classe A implique que les
destructeurs implicites ou explicites des classes héritées sont virtuels
aussi:
Soit à dire est-ce que ces déclarations :
class A
{
public:
virtuel ~A() {};
};
class B : public A
{
public:
// pas de destructeur explicite
// ou destructeur explicite sans mot clef "virtuel"
};
class C : public B
public:
// pas de destructeur explicite
// ou destructeur explicite sans mot clef "virtuel"
};
suffisent pour utiliser le code suivant sans risque de fuite mémoire:
B *ptr1;
B *ptr2;
ptr1 = new B;
ptr2 = new C;
delete ptr1;
delete ptr2;
ou bien dois-je obligatoirement déclarer les classes B et C comme ceci:
class B : public A
{
public:
virtual ~B(){/* implémentation éventuelle */};
};
class C : public B
public:
virtual ~C(){/* implémentation éventuelle */};
};
Merci d'avance pour toute réponse.
--
Edrusb
edrusba@free.fr (supprimer le 'a')

Poser une question


Il est nécessaire que toute classe dont une autre va dériver possède un
destructeur virtuel. Seule la classe tout en bas de la hiérarchie, dont
aucune autre va dériver, peut ne pas avoir de destructeur virtuel.
Le destructeur virtuel _DOIT_ être implémenté pour toute classe mère,
afin de ne pas avoir de fuite lors de l'utilisation du polymorphisme par
le biais d'une classe de base.
Alp
La virtualité d'une fonction s'hérite. Si le destructeur de
n'importe quelle classe de base est déclaré virtuel, le
destructeur de la classe en question est aussi virtuel, même
s'il n'est pas déclaré tel, et même s'il est généré
implicitement par le compilateur.
Tout à fait. Sauf que la risque n'est pas une fuite de mémoire,
mais plutôt un comportement indéfini.
--
James Kanze (Gabi Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Ah j'aurais pensé qu'il y aurait exception ici.
Cependant pour échapper à des comportements indéfinis, il vaut mieux
redéfinir un destructeur (virtuel si la classe sera dérivée à son tour).
Merci à tous les deux pour vos réponses.
--
Edrusb
(supprimer le 'a')
Pourquoi ?
Encore, pourquoi ? La seule raison que je vois, c'est
l'habituelle, qu'on définit toujours un destructeur, même vide,
afin d'éviter qu'il soit inline.
--
James Kanze (Gabi Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34