Je voudrais faire un truc, et d'un je sais pas comment faire et dedeux je
crois que ce que je veux faire s'appelle le polymorphisme.
Explications :
J'ai une classe parent et des classes enfants dérivés de parent.
Toutes les instances de mes classes enfants sont stockées dans une liste de
pointeurs.
Quand je veux accéder à une variable membre commune à toutes les classes
enfants par héritage de la classe parent, je caste avec le type parent :
(parent *)list(i)->ma_variable = 0;
Par contre, j'aimerais appeler une fonctions membre dont le prototype est
présent dans la classe parent et redéclarée dans toutes les classes enfants
car pour chaque classe enfant le code de cette fonction diffère. Mais je ne
peux pas faire :
(parent *)list(i)->ma_fonction();
car j'appelle celle de parent, et je ne peux pas caster avec le type enfant
correspondant car je ne sais quel pointeur de la liste va etre utilisé...
Comment faire pour que :
list(i)->ma_fonction();
appelle la fonction membre de la classe enfant désigné par le pointeur
list(i) ?
Peut être simplement en utilisant le mot-clé "virtual" dans ta classe parent et enfant:
Le fait de déclarer la fonction en "virtual" dans la classe parent suffit. Le mettre dans la classe enfant ou non est une question de goût.
Vincent
-- vmime, une bibliothèque C++ sous licence GPL pour parser et générer des messages au format MIME : http://www.sourceforge.net/projects/vmime/
Thomas Parle
"PurL" a écrit dans le message de news: bp2a7q$53q$
Bonjour,
Je voudrais faire un truc, et d'un je sais pas comment faire et dedeux je crois que ce que je veux faire s'appelle le polymorphisme.
Tout à fait. C'est avec ce principe que le type de l'objet peut être déterminé au runtime pour accéder aux 'bonnes' méthodes d'un objet, même si tu passes par un pointeur sur sa classe parente.
Comment faire pour que :
list(i)->ma_fonction();
appelle la fonction membre de la classe enfant désigné par le pointeur list(i) ?
Peut être simplement en utilisant le mot-clé "virtual" dans ta classe parent et enfant:
virtual ma_fonction() { ... }
"PurL" <purl-nospam@chez.com> a écrit dans le message de news:
bp2a7q$53q$1@news-reader4.wanadoo.fr...
Bonjour,
Je voudrais faire un truc, et d'un je sais pas comment faire et dedeux je
crois que ce que je veux faire s'appelle le polymorphisme.
Tout à fait. C'est avec ce principe que le type de l'objet peut être
déterminé au runtime pour accéder aux 'bonnes' méthodes d'un objet, même si
tu passes par un pointeur sur sa classe parente.
Comment faire pour que :
list(i)->ma_fonction();
appelle la fonction membre de la classe enfant désigné par le pointeur
list(i) ?
Peut être simplement en utilisant le mot-clé "virtual" dans ta classe parent
et enfant:
"PurL" a écrit dans le message de news: bp2a7q$53q$
Bonjour,
Je voudrais faire un truc, et d'un je sais pas comment faire et dedeux je crois que ce que je veux faire s'appelle le polymorphisme.
Tout à fait. C'est avec ce principe que le type de l'objet peut être déterminé au runtime pour accéder aux 'bonnes' méthodes d'un objet, même si tu passes par un pointeur sur sa classe parente.
Comment faire pour que :
list(i)->ma_fonction();
appelle la fonction membre de la classe enfant désigné par le pointeur list(i) ?
Peut être simplement en utilisant le mot-clé "virtual" dans ta classe parent et enfant:
virtual ma_fonction() { ... }
Benoit Rousseau
[Question sur les destructeurs virtuels à la fin]
PurL wrote:
Bonjour,
Je voudrais faire un truc, et d'un je sais pas comment faire et dedeux je crois que ce que je veux faire s'appelle le polymorphisme. Explications :
[...]
Comment faire pour que :
list(i)->ma_fonction();
appelle la fonction membre de la classe enfant désigné par le pointeur list(i) ?
Il s'agit bien de polymorphisme et tu obtiendras ce que tu cherches en utilisant des fonctions virtuelles. Le fait de déclarer une fonction 'virtual' dans une classe indique que cette fonction pourra être spécialisé pour chacun de ses enfants.
class Base { public: virtual void ma_fonction() = 0; //Fonction virtuelle pure virtual void ma_fonction() {} ; //Fonction virtuelle par défaut };
Si tu utilise un fonction virtuelle pure, elle devra obligatoirement être implémentée dans les objets dérivés que tu instancieras (Tu ne pourras pas avoir d'objet de type Base par exemple).
Si tu utilise une fonction virtuelle définie par défaut, elle sera appelée si tu ne la redéfinie pas dans l'objet dérivé.
Une classe dérivée devrait resembler à ca :
class Impl : class Base { public: void ma_fonction() {...}; };
J'ai lu quelque part dans ces news qu'il fallait déclarer le destructeur de base comme virtuel ? C'est Bjarne qui a dit ca je crois dans son bouquin aussi. Dans quelles conditions est-ce vrai ? (J'ai pas le bouquin et pas l'argent pour l'acheter non plus)
-------------------------------------------- Benoît Rousseau : roussebe at spray dot se Jouez en programmant : http://realtimebattle.sourceforge.net/
[Question sur les destructeurs virtuels à la fin]
PurL wrote:
Bonjour,
Je voudrais faire un truc, et d'un je sais pas comment faire et dedeux je
crois que ce que je veux faire s'appelle le polymorphisme.
Explications :
[...]
Comment faire pour que :
list(i)->ma_fonction();
appelle la fonction membre de la classe enfant désigné par le pointeur
list(i) ?
Il s'agit bien de polymorphisme et tu obtiendras ce que tu cherches en
utilisant des fonctions virtuelles.
Le fait de déclarer une fonction 'virtual' dans une classe indique que
cette fonction pourra être spécialisé pour chacun de ses enfants.
class Base {
public:
virtual void ma_fonction() = 0; //Fonction virtuelle pure
virtual void ma_fonction() {} ; //Fonction virtuelle par défaut
};
Si tu utilise un fonction virtuelle pure, elle devra obligatoirement
être implémentée dans les objets dérivés que tu instancieras (Tu ne
pourras pas avoir d'objet de type Base par exemple).
Si tu utilise une fonction virtuelle définie par défaut, elle sera
appelée si tu ne la redéfinie pas dans l'objet dérivé.
Une classe dérivée devrait resembler à ca :
class Impl : class Base {
public:
void ma_fonction() {...};
};
J'ai lu quelque part dans ces news qu'il fallait déclarer le destructeur
de base comme virtuel ? C'est Bjarne qui a dit ca je crois dans son
bouquin aussi. Dans quelles conditions est-ce vrai ? (J'ai pas le
bouquin et pas l'argent pour l'acheter non plus)
--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/
Je voudrais faire un truc, et d'un je sais pas comment faire et dedeux je crois que ce que je veux faire s'appelle le polymorphisme. Explications :
[...]
Comment faire pour que :
list(i)->ma_fonction();
appelle la fonction membre de la classe enfant désigné par le pointeur list(i) ?
Il s'agit bien de polymorphisme et tu obtiendras ce que tu cherches en utilisant des fonctions virtuelles. Le fait de déclarer une fonction 'virtual' dans une classe indique que cette fonction pourra être spécialisé pour chacun de ses enfants.
class Base { public: virtual void ma_fonction() = 0; //Fonction virtuelle pure virtual void ma_fonction() {} ; //Fonction virtuelle par défaut };
Si tu utilise un fonction virtuelle pure, elle devra obligatoirement être implémentée dans les objets dérivés que tu instancieras (Tu ne pourras pas avoir d'objet de type Base par exemple).
Si tu utilise une fonction virtuelle définie par défaut, elle sera appelée si tu ne la redéfinie pas dans l'objet dérivé.
Une classe dérivée devrait resembler à ca :
class Impl : class Base { public: void ma_fonction() {...}; };
J'ai lu quelque part dans ces news qu'il fallait déclarer le destructeur de base comme virtuel ? C'est Bjarne qui a dit ca je crois dans son bouquin aussi. Dans quelles conditions est-ce vrai ? (J'ai pas le bouquin et pas l'argent pour l'acheter non plus)
-------------------------------------------- Benoît Rousseau : roussebe at spray dot se Jouez en programmant : http://realtimebattle.sourceforge.net/
Christophe Lephay
Benoit Rousseau wrote:
J'ai lu quelque part dans ces news qu'il fallait déclarer le destructeur de base comme virtuel ? C'est Bjarne qui a dit ca je crois dans son bouquin aussi. Dans quelles conditions est-ce vrai ? (J'ai pas le bouquin et pas l'argent pour l'acheter non plus)
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu l'utilises via des pointeurs. Dans ce cas, il est probable que tu effaces l'objet dérivé par un pointeur sur la classe de base, et c'est le destructeur de la classe de base qui sera donc appelé à moins que ce dernier n'y soit déclaré virtuel.
Tu n'as pas le problème si tu "polymorphises" à travers des références, vu que tu n'as pas véritablement création et destruction d'objets par ce biais, mais références et pointeurs sont si proches sémantiquement parlant, que ce serait un peu hasardeux de demander aux utilisateurs de ta hiérarchie de ne pas utiliser de pointeurs mais que des références.
Conclusion : dès que tu veux du polymorphisme (notemment dès qu'une fonction est virtuelle), il faut fournir un destructeur virtuel (même si on peut toujours imaginer des cas improbables où c'est inutile)...
Chris
Benoit Rousseau wrote:
J'ai lu quelque part dans ces news qu'il fallait déclarer le
destructeur
de base comme virtuel ? C'est Bjarne qui a dit ca je crois dans son
bouquin aussi. Dans quelles conditions est-ce vrai ? (J'ai pas le
bouquin et pas l'argent pour l'acheter non plus)
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu
l'utilises via des pointeurs. Dans ce cas, il est probable que tu effaces
l'objet dérivé par un pointeur sur la classe de base, et c'est le
destructeur de la classe de base qui sera donc appelé à moins que ce dernier
n'y soit déclaré virtuel.
Tu n'as pas le problème si tu "polymorphises" à travers des références, vu
que tu n'as pas véritablement création et destruction d'objets par ce biais,
mais références et pointeurs sont si proches sémantiquement parlant, que ce
serait un peu hasardeux de demander aux utilisateurs de ta hiérarchie de ne
pas utiliser de pointeurs mais que des références.
Conclusion : dès que tu veux du polymorphisme (notemment dès qu'une fonction
est virtuelle), il faut fournir un destructeur virtuel (même si on peut
toujours imaginer des cas improbables où c'est inutile)...
J'ai lu quelque part dans ces news qu'il fallait déclarer le destructeur de base comme virtuel ? C'est Bjarne qui a dit ca je crois dans son bouquin aussi. Dans quelles conditions est-ce vrai ? (J'ai pas le bouquin et pas l'argent pour l'acheter non plus)
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu l'utilises via des pointeurs. Dans ce cas, il est probable que tu effaces l'objet dérivé par un pointeur sur la classe de base, et c'est le destructeur de la classe de base qui sera donc appelé à moins que ce dernier n'y soit déclaré virtuel.
Tu n'as pas le problème si tu "polymorphises" à travers des références, vu que tu n'as pas véritablement création et destruction d'objets par ce biais, mais références et pointeurs sont si proches sémantiquement parlant, que ce serait un peu hasardeux de demander aux utilisateurs de ta hiérarchie de ne pas utiliser de pointeurs mais que des références.
Conclusion : dès que tu veux du polymorphisme (notemment dès qu'une fonction est virtuelle), il faut fournir un destructeur virtuel (même si on peut toujours imaginer des cas improbables où c'est inutile)...
Chris
PurL
Merci à tous, ca marche impec :) y'a que le coup du destructeur virtuel que j'ai pas saisie mais je verrais à l'usage...
PurL
Merci à tous, ca marche impec :)
y'a que le coup du destructeur virtuel que j'ai pas saisie mais je verrais à
l'usage...
Merci à tous, ca marche impec :) y'a que le coup du destructeur virtuel que j'ai pas saisie mais je verrais à l'usage...
PurL
Benoit Rousseau
PurL wrote:
Merci à tous, ca marche impec :) y'a que le coup du destructeur virtuel que j'ai pas saisie mais je verrais à l'usage...
PurL
C'est comme pour les fonctions virtuelles... Si tu as class A { };
class B { public: B( ) : t( new Type ) ) {} ~B() { if( t ) delete t ; } Type * t; };
et que tu fais A* ab = new B( ) delete ab; //Appel A::~A() et non pas B::~B()
Il faut que le destructeur soit virtuel dans A si tu veux que l'objet soit détruit correctement.
Christophe disait également que ce problème n'avait lieu que dans le cadre de polymorphisme avec des pointeurs et qu'il n'y avait pas ce problème pour les références :
{ B b; } //Appele du destructeur B::~B()
Mais quand on fait du polymorphisme on se trouve plus souvent dans le premier cas je pense.
C'est bien ça ?
-- -------------------------------------------- Benoît Rousseau : roussebe at spray dot se Jouez en programmant : http://realtimebattle.sourceforge.net/
PurL wrote:
Merci à tous, ca marche impec :)
y'a que le coup du destructeur virtuel que j'ai pas saisie mais je verrais à
l'usage...
PurL
C'est comme pour les fonctions virtuelles...
Si tu as
class A {
};
class B {
public:
B( ) : t( new Type ) ) {}
~B() { if( t ) delete t ; }
Type * t;
};
et que tu fais
A* ab = new B( )
delete ab; //Appel A::~A() et non pas B::~B()
Il faut que le destructeur soit virtuel dans A si tu veux que l'objet
soit détruit correctement.
Christophe disait également que ce problème n'avait lieu que dans le
cadre de polymorphisme avec des pointeurs et qu'il n'y avait pas ce
problème pour les références :
{
B b;
} //Appele du destructeur B::~B()
Mais quand on fait du polymorphisme on se trouve plus souvent dans le
premier cas je pense.
C'est bien ça ?
--
--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/
Merci à tous, ca marche impec :) y'a que le coup du destructeur virtuel que j'ai pas saisie mais je verrais à l'usage...
PurL
C'est comme pour les fonctions virtuelles... Si tu as class A { };
class B { public: B( ) : t( new Type ) ) {} ~B() { if( t ) delete t ; } Type * t; };
et que tu fais A* ab = new B( ) delete ab; //Appel A::~A() et non pas B::~B()
Il faut que le destructeur soit virtuel dans A si tu veux que l'objet soit détruit correctement.
Christophe disait également que ce problème n'avait lieu que dans le cadre de polymorphisme avec des pointeurs et qu'il n'y avait pas ce problème pour les références :
{ B b; } //Appele du destructeur B::~B()
Mais quand on fait du polymorphisme on se trouve plus souvent dans le premier cas je pense.
C'est bien ça ?
-- -------------------------------------------- Benoît Rousseau : roussebe at spray dot se Jouez en programmant : http://realtimebattle.sourceforge.net/
kanze
Benoit Rousseau wrote in message news:<3fb4b8c2$0$10314$...
J'ai lu quelque part dans ces news qu'il fallait déclarer le destructeur de base comme virtuel ? C'est Bjarne qui a dit ca je crois dans son bouquin aussi. Dans quelles conditions est-ce vrai ? (J'ai pas le bouquin et pas l'argent pour l'acheter non plus)
Quand tu fais un delete à travers un pointeur vers la base. Si le type statique n'est pas le même que le type dynamique, c'est un comportement indéfini si le destructeur n'est pas virtuel.
En général, quand tu conçois un type pour servir de type de base, tu t'attends à ce que les gens le manipulent à travers un pointeur au type de base. En général, donc, quand tu conçois un type pour servir de type de base, tu dois déclarer le destructeur virtuel.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
Benoit Rousseau <not.provided@no.spam> wrote in message
news:<3fb4b8c2$0$10314$ba620e4c@reader0.news.skynet.be>...
J'ai lu quelque part dans ces news qu'il fallait déclarer le
destructeur de base comme virtuel ? C'est Bjarne qui a dit ca je crois
dans son bouquin aussi. Dans quelles conditions est-ce vrai ? (J'ai
pas le bouquin et pas l'argent pour l'acheter non plus)
Quand tu fais un delete à travers un pointeur vers la base. Si le type
statique n'est pas le même que le type dynamique, c'est un comportement
indéfini si le destructeur n'est pas virtuel.
En général, quand tu conçois un type pour servir de type de base, tu
t'attends à ce que les gens le manipulent à travers un pointeur au type
de base. En général, donc, quand tu conçois un type pour servir de type
de base, tu dois déclarer le destructeur virtuel.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
Benoit Rousseau wrote in message news:<3fb4b8c2$0$10314$...
J'ai lu quelque part dans ces news qu'il fallait déclarer le destructeur de base comme virtuel ? C'est Bjarne qui a dit ca je crois dans son bouquin aussi. Dans quelles conditions est-ce vrai ? (J'ai pas le bouquin et pas l'argent pour l'acheter non plus)
Quand tu fais un delete à travers un pointeur vers la base. Si le type statique n'est pas le même que le type dynamique, c'est un comportement indéfini si le destructeur n'est pas virtuel.
En général, quand tu conçois un type pour servir de type de base, tu t'attends à ce que les gens le manipulent à travers un pointeur au type de base. En général, donc, quand tu conçois un type pour servir de type de base, tu dois déclarer le destructeur virtuel.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
Bertrand Motuelle
"Christophe Lephay" schrieb im Newsbeitrag news:bp2m9p$amd$
Benoit Rousseau wrote:
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu l'utilises via des pointeurs. Dans ce cas, il est probable que tu effaces l'objet dérivé par un pointeur sur la classe de base, et c'est le destructeur de la classe de base qui sera donc appelé à moins que ce dernier
n'y soit déclaré virtuel.
Dans la pratique, c'est généralement ce qui se passe (seul le destructeur de la classe de base est appelé). Mais formellement c'est un comportement indéfini.
Bertrand.
"Christophe Lephay" <christophe-lephay@wanadoo.fr> schrieb im Newsbeitrag
news:bp2m9p$amd$1@news-reader1.wanadoo.fr...
Benoit Rousseau wrote:
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu
l'utilises via des pointeurs. Dans ce cas, il est probable que tu effaces
l'objet dérivé par un pointeur sur la classe de base, et c'est le
destructeur de la classe de base qui sera donc appelé à moins que ce
dernier
n'y soit déclaré virtuel.
Dans la pratique, c'est généralement ce qui se passe (seul le destructeur de
la classe de base est appelé).
Mais formellement c'est un comportement indéfini.
"Christophe Lephay" schrieb im Newsbeitrag news:bp2m9p$amd$
Benoit Rousseau wrote:
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu l'utilises via des pointeurs. Dans ce cas, il est probable que tu effaces l'objet dérivé par un pointeur sur la classe de base, et c'est le destructeur de la classe de base qui sera donc appelé à moins que ce dernier
n'y soit déclaré virtuel.
Dans la pratique, c'est généralement ce qui se passe (seul le destructeur de la classe de base est appelé). Mais formellement c'est un comportement indéfini.
Bertrand.
Benoit Rousseau
Bertrand Motuelle wrote:
"Christophe Lephay" schrieb im Newsbeitrag news:bp2m9p$amd$
Benoit Rousseau wrote:
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu l'utilises via des pointeurs. Dans ce cas, il est probable que tu effaces l'objet dérivé par un pointeur sur la classe de base, et c'est le destructeur de la classe de base qui sera donc appelé à moins que ce
dernier
n'y soit déclaré virtuel.
Dans la pratique, c'est généralement ce qui se passe (seul le destructeur de la classe de base est appelé). Non, il faut que le destructeur de la classe dérivée soit appelé, sinon
tu ne détruis pas correctement les objets de cette classe (pas de delete des objets dynamiques par exemple) ...
Mais formellement c'est un comportement indéfini. C'est surtout une non-libération des espaces alloués...
-- -------------------------------------------- Benoît Rousseau : roussebe at spray dot se Jouez en programmant : http://realtimebattle.sourceforge.net/
Bertrand Motuelle wrote:
"Christophe Lephay" <christophe-lephay@wanadoo.fr> schrieb im Newsbeitrag
news:bp2m9p$amd$1@news-reader1.wanadoo.fr...
Benoit Rousseau wrote:
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu
l'utilises via des pointeurs. Dans ce cas, il est probable que tu effaces
l'objet dérivé par un pointeur sur la classe de base, et c'est le
destructeur de la classe de base qui sera donc appelé à moins que ce
dernier
n'y soit déclaré virtuel.
Dans la pratique, c'est généralement ce qui se passe (seul le destructeur de
la classe de base est appelé).
Non, il faut que le destructeur de la classe dérivée soit appelé, sinon
tu ne détruis pas correctement les objets de cette classe (pas de delete
des objets dynamiques par exemple) ...
Mais formellement c'est un comportement indéfini.
C'est surtout une non-libération des espaces alloués...
--
--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/
"Christophe Lephay" schrieb im Newsbeitrag news:bp2m9p$amd$
Benoit Rousseau wrote:
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu l'utilises via des pointeurs. Dans ce cas, il est probable que tu effaces l'objet dérivé par un pointeur sur la classe de base, et c'est le destructeur de la classe de base qui sera donc appelé à moins que ce
dernier
n'y soit déclaré virtuel.
Dans la pratique, c'est généralement ce qui se passe (seul le destructeur de la classe de base est appelé). Non, il faut que le destructeur de la classe dérivée soit appelé, sinon
tu ne détruis pas correctement les objets de cette classe (pas de delete des objets dynamiques par exemple) ...
Mais formellement c'est un comportement indéfini. C'est surtout une non-libération des espaces alloués...
-- -------------------------------------------- Benoît Rousseau : roussebe at spray dot se Jouez en programmant : http://realtimebattle.sourceforge.net/
Bertrand Motuelle
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu l'utilises via des pointeurs. Dans ce cas, il est probable que tu effaces
l'objet dérivé par un pointeur sur la classe de base, et c'est le destructeur de la classe de base qui sera donc appelé à moins que ce dernier n'y soit déclaré virtuel.
Dans la pratique, c'est généralement ce qui se passe (seul le destructeur de
la classe de base est appelé). Non, il faut que le destructeur de la classe dérivée soit appelé, sinon
tu ne détruis pas correctement les objets de cette classe (pas de delete des objets dynamiques par exemple) ...
Mais formellement c'est un comportement indéfini. C'est surtout une non-libération des espaces alloués...
Manifestement, je me suis mal fait comprendre: struct A { /* pas de destructeur virtuel */ } struct B : A {}
A* a = new B; delete a; // bang
Selon la norme, la ligne delete a; a un comportement indéfini car A n'a pas de destructeur virtuel. Cela pourrait par exemple formatter le disque dur de ton voisin (dans la pratique, ce comportement indéfini se borne souvent à ne pas appeler le destructeur de B). Donc quand on veut utiliser le polymorphisme, il est de bon ton de déclarer le destructeur de la classe de base virtuel.
Bertrand.
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu
l'utilises via des pointeurs. Dans ce cas, il est probable que tu
effaces
l'objet dérivé par un pointeur sur la classe de base, et c'est le
destructeur de la classe de base qui sera donc appelé à moins que ce
dernier n'y soit déclaré virtuel.
Dans la pratique, c'est généralement ce qui se passe (seul le
destructeur de
la classe de base est appelé).
Non, il faut que le destructeur de la classe dérivée soit appelé, sinon
tu ne détruis pas correctement les objets de cette classe (pas de delete
des objets dynamiques par exemple) ...
Mais formellement c'est un comportement indéfini.
C'est surtout une non-libération des espaces alloués...
Manifestement, je me suis mal fait comprendre:
struct A { /* pas de destructeur virtuel */ }
struct B : A {}
A* a = new B;
delete a; // bang
Selon la norme, la ligne delete a; a un comportement indéfini car A n'a pas
de destructeur virtuel.
Cela pourrait par exemple formatter le disque dur de ton voisin (dans la
pratique, ce comportement indéfini se borne souvent à ne pas appeler le
destructeur de B).
Donc quand on veut utiliser le polymorphisme, il est de bon ton de déclarer
le destructeur de la classe de base virtuel.
Dès que tu utilises le polymorphisme, il y a de grandes chances que tu l'utilises via des pointeurs. Dans ce cas, il est probable que tu effaces
l'objet dérivé par un pointeur sur la classe de base, et c'est le destructeur de la classe de base qui sera donc appelé à moins que ce dernier n'y soit déclaré virtuel.
Dans la pratique, c'est généralement ce qui se passe (seul le destructeur de
la classe de base est appelé). Non, il faut que le destructeur de la classe dérivée soit appelé, sinon
tu ne détruis pas correctement les objets de cette classe (pas de delete des objets dynamiques par exemple) ...
Mais formellement c'est un comportement indéfini. C'est surtout une non-libération des espaces alloués...
Manifestement, je me suis mal fait comprendre: struct A { /* pas de destructeur virtuel */ } struct B : A {}
A* a = new B; delete a; // bang
Selon la norme, la ligne delete a; a un comportement indéfini car A n'a pas de destructeur virtuel. Cela pourrait par exemple formatter le disque dur de ton voisin (dans la pratique, ce comportement indéfini se borne souvent à ne pas appeler le destructeur de B). Donc quand on veut utiliser le polymorphisme, il est de bon ton de déclarer le destructeur de la classe de base virtuel.