Héritage et destructeur - C++ - Programmation
Marsh Posté le 17-04-2003 à 05:45:17
Il est virtuel ton destructeur ?
LeGreg
Marsh Posté le 17-04-2003 à 08:29:37
deltaden a écrit : salut,
|
A priori si ton objet est de type Gate je vois pas pkoi ce serait le destructeur de ANDGate qui serait appelé...
Pkoi tu déclares pas directement ton objet en tant qu'ANDGate en le castant en Gate quand tu en as besoin?
Marsh Posté le 17-04-2003 à 08:34:33
par ce que c'est pour faire du polymorphisme qui passe par des pointeurs de classe mère. L'intéret est donc de ne pas avoir à faire de cast et on ne se soucie pas du type réel de l'objet. Les mécanismes virtuels sont là.
Marsh Posté le 17-04-2003 à 08:36:05
Ca sent le destructeur de Gate pas virtuel ça
Marsh Posté le 17-04-2003 à 08:37:38
ReplyMarsh Posté le 17-04-2003 à 08:39:04
J'ai rien dit...'suis pas au niveau là on dirait...:lol:
Rassurez-moi, ct pas tout à fait idiot qd même...?
[Edit]
Citation : J'ai un destructeur définis dans ma classe mère et dans certaines classes filles |
Ca risque pas de poser pb s'il le passe en virtuel?
(Si je dis une connerie tapez pas trop fort...:D)
Marsh Posté le 17-04-2003 à 08:47:56
++Taz a écrit : t'as qu'à dire que t'es mal réveillé |
voir edit...mais si c encore une connerie je pars de suite chercher un cours de c++ moi (ca faisait un moment que j'y avais plus touché, mais pdt 6 mois faut que je m'y remette, alors ce sera pas perdu!).
Marsh Posté le 17-04-2003 à 08:49:30
skeye a écrit : |
Tant qu'il est pas virtuel pur, non.
Au fait, c'est possible un destructeur virtuel pur ?
Marsh Posté le 17-04-2003 à 08:50:23
kadreg a écrit : |
bon, c'est décidé, ce matin c'est révisions!
Marsh Posté le 17-04-2003 à 08:51:22
va te chercehr un cours. totues les classes meres ou filles on un destrcuteur. le destructeur des classe filles appellent naturellement le destructeur de la classe mère. le porblème c'est qu'avec un Mere* pointant vers une instance de Fille (ouhla) l'appel du destructeur (par delete) se contente par défaut d'appeler le destructeur de Mere (normal). il faut donc rajouter le mécanisme d'indirection virtuel pour que ça soit le destructeur du type réel de l'objet pointé qui soit appelé
Marsh Posté le 17-04-2003 à 08:56:35
++Taz a écrit : va te chercehr un cours. totues les classes meres ou filles on un destrcuteur. le destructeur des classe filles appellent naturellement le destructeur de la classe mère. le porblème c'est qu'avec un Mere* pointant vers une instance de Fille (ouhla) l'appel du destructeur (par delete) se contente par défaut d'appeler le destructeur de Mere (normal). il faut donc rajouter le mécanisme d'indirection virtuel pour que ça soit le destructeur du type réel de l'objet pointé qui soit appelé |
C'est ça qui n'apparait pas (ou plus...) dans un seul recoin de ma cervelle...Le reste ca allait!
Marsh Posté le 17-04-2003 à 08:57:05
kadreg a écrit : |
Après test, non
Marsh Posté le 17-04-2003 à 09:02:39
pourquoi? par ce que toutes classe doit avoir un constructeur et un destructeur.
Marsh Posté le 17-04-2003 à 09:33:04
Au cas où certains auraient besoin comme moi de se raffraichir la mémoire, l'explication est ici:
http://casteyde.christian.free.fr/ [...] x3673.html
[edit]
Dans ma tête n'existaient plus que les virtuelles pures...Ce qui explique ma question!
Marsh Posté le 17-04-2003 à 09:38:45
kadreg a écrit : |
pas besoin de test:
le destructeur de la classe mere est appelé
quoi qu'il arrive. Le minimum que tu puisses
faire c'est de ne rien faire pendant la destruction.
(un destructeur virtuel vide).
LeGreg
Marsh Posté le 17-04-2003 à 09:43:10
kadreg a écrit : |
Si c'est possible
Il faut faire un destructeur virtuel pur avec une implémentation.
Un truc du genre :
Code :
|
Marsh Posté le 17-04-2003 à 09:45:44
Kristoph a écrit :
|
Dans ma tête c'est contradictoire comme expression ça...
Marsh Posté le 17-04-2003 à 09:51:17
ReplyMarsh Posté le 17-04-2003 à 10:28:20
++Taz a écrit : ça l'est! |
(je me le garde au chaud pour faire un questionnaire de C++ pour les entretiens d'embauche)
Marsh Posté le 17-04-2003 à 10:36:29
kadreg a écrit : |
ca paye bien? je sais répondre...
Marsh Posté le 17-04-2003 à 14:08:19
ben oui, en effet, je l'avais pas déclarée virtuelle.
je commence en C++ là, alors il y a qlqs trucs où je suis un peu paumé...si je pose de bête question, c'est pas ma faute...
à+ et merci
Marsh Posté le 17-04-2003 à 20:09:22
skeye a écrit : |
Efficient C++ seconde edition. Testé à l'instant avec g++ 2.96. Ça marche très bien.
J'aimerais bien faire le test aussi avec gcc 3.2 mais j'ai pas ça sous la main maintenant. Voici le code :
Code :
|
Et le resultat :
Code :
|
Marsh Posté le 17-04-2003 à 20:15:46
c'est un bug. comment le destructeur de machin et constate les dégats. je regarde s'il y a des rapports la dessus.
Marsh Posté le 17-04-2003 à 20:18:07
++Taz a écrit : c'est un bug. comment le destructeur de machin et constate les dégats. je regarde s'il y a des rapports la dessus. |
Je ne comprends pas ce que tu veux dire par la ?
Marsh Posté le 17-04-2003 à 20:29:26
je sais pas, conceptuellement une virtuelle pure implémentée, ça n'a pas de sens. L'un des inetert des fonctions virtuelles pures, c'est aussi de réduir le temps de compilation en différent l'implémentation. et je n'ai jamais vu ça. je cherche une référence pour faire le point
eidt: je trouve pas.
Marsh Posté le 17-04-2003 à 20:35:11
C'est clair que définir une fonction comme virtuelle pure correspond à prévenir le compilo qu'on ne va pas donner de corps à cette fonction dans cette classe mais dans les classes héritantes ...
Normalement, c'est à cause de ces déclarations que le compilo peut savoir qu'une classe est abstraite et qu'on ne peut donc pas l'instancier ...
Implémenter une fonction est forcément illogique ... Autant la mettre simplement en virtuel, si c'est pour lui donner un corps ...
Marsh Posté le 17-04-2003 à 20:37:50
theShOcKwAvE a écrit : C'est clair que définir une fonction comme virtuelle pure correspond à prévenir le compilo qu'on ne va pas donner de corps à cette fonction dans cette classe mais dans les classes héritantes ... |
Explication de Meyers sous la forme d'une question :
"Comment faire une classe abstraite sans aucune méthode ?"
Réponse : Un destructeur virtuel pur.
Marsh Posté le 17-04-2003 à 20:42:07
oui mais il faut donner une implémentation, sur.
je viens de parler avec une pointure, et apparemment rien n'empeche d'implementer une virtuelle pure. cette personne est d'accord que cela n'a aucun sens et devrait etre interdit (il y a eu des proposals dans ce sens). son sentiment, que je partage, est que si une fonction virutelle pure f est munie d'une implémentation, évidemment la pureté est violée (ouh la!) et qu'il vaut mieux faire de cette manière
Code :
|
Marsh Posté le 17-04-2003 à 20:43:15
theShOcKwAvE a écrit : C'est vrai que ca aurait pu être un problème con ... |
je suis d'accord, c'est une mauvaise permission. Utiliser cette liberté du C++ sème la confusion
Marsh Posté le 17-04-2003 à 20:49:34
pour la rendre abstraite il suffit de ne pas lui donner
de vtable genre "__declspec(novtable)" (c'est pas une fonction
du standard mais comme "__declspec(deprecated)" ca peut s'averer utile).
Dans ce cas elle peut etre abstraite et avoir un corps
defini pour chaque fonction virtuelle.
(par contre tu ne paies pas le cout de la table
virtuelle pour chaque classe abstraite).
LeGreg
Marsh Posté le 17-04-2003 à 20:50:02
Kristoph a écrit : |
ça serait mieux des constructeurs protected il me semble
Marsh Posté le 17-04-2003 à 21:06:27
++Taz a écrit : ça serait mieux des constructeurs protected il me semble |
Je sais pas, faudrait que je relise le livre, mais je ne l'ai pas sous la main. Scott Meyers c'est aussi une grosse pointure du C++ il me semble
Marsh Posté le 17-04-2003 à 21:08:25
certes. mais beaucoup s'accord à dire qu'un destructeur virtuel pure n'a vraiment aps de sens, puisque que chaque classe est muni d'un destructeur.
Marsh Posté le 23-07-2012 à 12:17:54
deltaden a écrit : salut,
|
je pense que les reponses que je vois sur cette page ne repondent pas tout a fait a la question qui est posee
si j'ai bien compris dans ton exemple ANDGate derive de la classe Gate,
tu cree une instance de la classe derivee ANDGate, que tu stockes dans un pointeur de la classe mere(par exemple pour lister plusieurs type de gate (ORGate, ANDGate, XORGate etc...) dans la meme liste de GATE.
le probleme c'est que lorsque tu veux detruire les elements de la liste de GATE, tu as perdu le type exact des tes "GATE"
tu peux faire appel au destructeur de la classe mere, mais son probleme c'est qu'il n'est pas complet, il va detruire les attributs communs aux GATE mais la memoire vive restera "polluee" par les attributs supplementaires de la classe derivee ANDGate.
dans l'autre sens quand on fait appel au destructeur d'une classe fille, celui de la classe mere est automatiquement appele, mais ce cas est le cas inverse et il est plus delicat
j'ai pas de solution absolue a ce probleme, tu peux par exemple creer une structure
enum TypeGATE
{
AND,
OR,
XOR
}
struct GATE_struct
{
GATE* pointeur;
TypeGATE type_gate;
}
ensuite ca donne
Gate *and_1 = new ANDGate();
GATE_struct ma_gate;
ma_gate.pointeur = and_1;
ma_gate.TypeGate = AND;
ensuite pour faire appel au destructeur tu fais
switch(ma_gate.TypeGate)
case AND:
delete (ANDGate *)(and_1);
c'est lourd et moche, j'espere que quelqu'un aura mieux
Marsh Posté le 23-07-2012 à 12:20:07
deltaden a écrit : salut,
|
je pense que les reponses que je vois sur cette page ne repondent pas tout a fait a la question qui est posee
si j'ai bien compris dans ton exemple ANDGate derive de la classe Gate,
tu cree une instance de la classe derivee ANDGate, que tu stockes dans un pointeur de la classe mere(par exemple pour lister plusieurs type de gate (ORGate, ANDGate, XORGate etc...) dans la meme liste de GATE.
le probleme c'est que lorsque tu veux detruire les elements de la liste de GATE, tu as perdu le type exact des tes "GATE"
tu peux faire appel au destructeur de la classe mere, mais son probleme c'est qu'il n'est pas complet, il va detruire les attributs communs aux GATE mais la memoire vive restera "polluee" par les attributs supplementaires de la classe derivee ANDGate.
dans l'autre sens quand on fait appel au destructeur d'une classe fille, celui de la classe mere est automatiquement appele, mais ce cas est le cas inverse et il est plus delicat
j'ai pas de solution absolue a ce probleme, tu peux par exemple creer une structure
enum TypeGATE
{
AND,
OR,
XOR
}
struct GATE_struct
{
GATE* pointeur;
TypeGATE type_gate;
}
ensuite ca donne
Gate *and_1 = new ANDGate();
GATE_struct ma_gate;
ma_gate.pointeur = and_1;
ma_gate.TypeGate = AND;
ensuite pour faire appel au destructeur tu fais
switch(ma_gate.TypeGate)
case AND:
delete (ANDGate *)(and_1);
c'est lourd et moche, j'espere que quelqu'un aura mieux
Marsh Posté le 23-07-2012 à 15:33:13
d'une part, j'espère qu'en 9 ans, l'auteur aura trouvé une solution à son problème.
D'autre part, ta proposition est mauvaise : c'est typiquement un cas où il faut passer par de la virtualité comme proposé dans les réponses plus haut
Edit : et pour ce qui est du problème d'empêcher l'instanciation de la classe mère (qui a conduit à la dérive sur le droit ou non d'implémenter une virtuelle pure), il y a une solution plus élégante : déclarer les constructeurs de la classe mère en protected.
Marsh Posté le 17-04-2003 à 04:12:45
salut,
j'ai un petit problème: j'ai une classe mère Gate qui est étendue par un certain nombre de classes. J'ai un destructeur définis dans ma classe mère et dans certaines classes filles, pour faire qlq delete.
Bon, mon problème est que si je fais ca:
tout marche comme il faut jusqu'au delete: c'est le destructeur de Gate qui est appelé, pas de celui ANDGate.
Est-ce que quelqu'un sait comment contourner ce problème (à part le delete (ANDGate*)and_1; qui marche mais qui est pas top)?
merci
---------------
"La Terre est le berceau de l'humanité, mais on ne passe pas toute sa vie au berceau." - Konstantine Tsiolkovski