[C++] une histoire de destructeur ...

une histoire de destructeur ... [C++] - C++ - Programmation

Marsh Posté le 21-10-2001 à 10:28:55    

Voila mon problème :
j'ai une classe avec des interfaces, ie en fait l'utilisateur demande une interface et tout se fait de manière transparente pour lui. Pour la construction, pas de problème, un ptit new qui renvoie un pointeur sur l'objet et ça roule. Mais ce qui me pose problème c'est pour la destruction ...
En fait, admettons que l'utilisateur ait eu un objet comme ça :  
CTruc *Objet = DonneMoiUneInterface ();
Et bien je voudrais ensuite que la destruction suive une syntaxe comme ça : Objet->Release (); ... Je sais le faire si c'est du genre ReleaseObjet (Objet), mais pas Objet->Release ().
Je m'explique : il faut par derrière faire un delete de la classe, ce qui ne pose aucun problème si c'est à partir d'une fonction tierce, mais m'en pose un gros si il est appelé à partir d'une fonction appartenant à la classe ...
Désolé je suis pas vraiment clair, mais si vous avez juste des idées ...

Reply

Marsh Posté le 21-10-2001 à 10:28:55   

Reply

Marsh Posté le 21-10-2001 à 10:49:23    

tiens c'est vraiment chelou :
à tout hasard après avoir écrit ce post j'ai qd même voulu essayez un truc :
dans ma fonction CTruc::Release (), je fais un appelle à delete[] this. Et ça ne fais pas planter !!  
Alors je voudrais savoir si ça fait bien ce que je veux, c'est à dire la même chose que si j'avais appellé depuis l'extérieur ce delete. En fait j'ai juste un doute parce que l'objet est détruit à partir d'une de ses propres fonctions, mais si ça se trouve c'est tout à fait normal et je me fais du soucis pour rien ...

Reply

Marsh Posté le 21-10-2001 à 14:55:50    

en gros, c'est à tes risques et perils, ca ne plante pas mais ca peut saloper la memoire cette histoire (chez mikeysoft, ils utilisent du code comme ca tt le temps avec activex). Si ton destructeur n'utilise plus d'attribut de la classe à detruire apres le delete, et si ds les destructeurs des parents c'est pareil, t'aura pas trop d'embettements.  
A mon avis, si t'as la possibilité, utilise un conteneur qui prend en charge la durée de vie de l'objet, c'est plus propre.

Reply

Marsh Posté le 21-10-2001 à 16:48:29    

ben en fait c'est la seule instruction du destructeur, et y a aucune instruction dans le destructeur parent, mais c'est vrai que je risque de passer à un conteneur pour être plus sur ...
merci de ta réponse

Reply

Marsh Posté le 21-10-2001 à 17:14:46    

Tu peux utiliser le delete this.
Mais il faut être sûr que l'objet a été crer avec new et non pas sur la pile.

Reply

Marsh Posté le 21-10-2001 à 19:26:16    

en fait je suis sur que l'objet est pas sur la pile parce que le constructeur est private, donc pas de danger de ce coté là.

 

[edtdd]--Message édité par freewol--[/edtdd]

Reply

Marsh Posté le 21-10-2001 à 20:21:04    

freewol a écrit a écrit :

tiens c'est vraiment chelou :
à tout hasard après avoir écrit ce post j'ai qd même voulu essayez un truc :
dans ma fonction CTruc::Release (), je fais un appelle à delete[] this. Et ça ne fais pas planter !!  
Alors je voudrais savoir si ça fait bien ce que je veux, c'est à dire la même chose que si j'avais appellé depuis l'extérieur ce delete. En fait j'ai juste un doute parce que l'objet est détruit à partir d'une de ses propres fonctions, mais si ça se trouve c'est tout à fait normal et je me fais du soucis pour rien ...  




 
pourquoi tu fais un delete[] this et pas un delete this, c'est comme ça avec le code de iunknown::release()

Reply

Marsh Posté le 22-10-2001 à 09:11:20    

wpk a écrit a écrit :

en gros, c'est à tes risques et perils, ca ne plante pas mais ca peut saloper la memoire cette histoire (chez mikeysoft, ils utilisent du code comme ca tt le temps avec activex). Si ton destructeur n'utilise plus d'attribut de la classe à detruire apres le delete, et si ds les destructeurs des parents c'est pareil, t'aura pas trop d'embettements.  
A mon avis, si t'as la possibilité, utilise un conteneur qui prend en charge la durée de vie de l'objet, c'est plus propre.  




:??:
peu importe...
 
si tu as alloue ton objet avec new tu le detruis avec delete
si tu as alloue ton abjet avec new[] tu le detruis avec delete[]
il faut simplement que cette instruction soit le derniere de ta fonction Release... et bien sur que cette fonction ne soit pas appellee par une methode de l'objet (ou alors en dernier)
Par contre dans les destructeurs ce ne change rien...

Reply

Marsh Posté le 22-10-2001 à 12:21:44    

ayachi a écrit a écrit :

 
 
pourquoi tu fais un delete[] this et pas un delete this, c'est comme ça avec le code de iunknown::release()  




 
Erreur d'écriture désolé, en réalité je fais bien un delete this. Par contre est-ce que tu pourrais préciser ce qu'est iunknown ?

Reply

Marsh Posté le 22-10-2001 à 12:24:58    

BENB a écrit a écrit :

 
:??:
peu importe...
 
si tu as alloue ton objet avec new tu le detruis avec delete
si tu as alloue ton abjet avec new[] tu le detruis avec delete[]
il faut simplement que cette instruction soit le derniere de ta fonction Release... et bien sur que cette fonction ne soit pas appellee par une methode de l'objet (ou alors en dernier)
Par contre dans les destructeurs ce ne change rien...  




 
Donc en procédant comme ça tu es sur que je n'aurais pas des bouts d'objet qui resteront dans la mémoire ? Si c'est sur ben c'est parfait c'est exactement ce qu'il me faut.
Et oui bien sur le delete this est la toute dernière opération exécutée sur l'objet.

Reply

Marsh Posté le 22-10-2001 à 12:24:58   

Reply

Marsh Posté le 22-10-2001 à 13:39:01    

freewol a écrit a écrit :

 
 
Donc en procédant comme ça tu es sur que je n'aurais pas des bouts d'objet qui resteront dans la mémoire ? Si c'est sur ben c'est parfait c'est exactement ce qu'il me faut.
Et oui bien sur le delete this est la toute dernière opération exécutée sur l'objet.  




Le veritable risque est plutot acceder a une ressource qui n'existe plus, par exemple en faisant un acces a un membre de l'objet apres sa destruction...
 
pense en particulier aux resolutions en fin de fonction...
par exemple un objet B sur la pile dans cette fonction (de l'objet A) dont le destructeur (de B) viendrait dereferencer l'objet (B) dans une liste de A or a la fin de la fonction A n'existe plus.... et comme l'appel du destructeur est implicite... on ne le vois pas...

Reply

Marsh Posté le 22-10-2001 à 13:43:03    

freewol
Par contre est-ce que tu pourrais préciser ce qu'est iunknown ?
C l´interface de base de tous les objets com.. Et c vrai que com/ole utilise le même genre de truc que toi, alias une instanciantion implicite et la possibilité d´obtenir des interfaces..
(personnellement j´aime pas du mais bon ;) )


---------------
Athlon64 s754 10*200MHz - R9800Pro - 512MB DDR200MHz - ZX6RR - Q2[SupOp] - Tutorial Video: multilangues, multisstitres
Reply

Marsh Posté le 22-10-2001 à 16:15:46    

H4dd3R a écrit a écrit :

 
C l´interface de base de tous les objets com.. Et c vrai que com/ole utilise le même genre de truc que toi, alias une instanciantion implicite et la possibilité d´obtenir des interfaces..
(personnellement j´aime pas du mais bon ;) )  




 
Et les objets com sont en open source ? Ca peut être intéressant ça ... On peut la trouver où la source ?
Qu'est-ce que tu entends par "instanciation implicite" ? Moi je trouve très agréable la gestion des interfaces, ça permet d'avoir une grande modularité du code ie très peu de modifs à faire du coté "client" pour obtenir des trucs très différents ... Enfin bon tout dépends des cas bien sur ...
Et donc je trouve la destruction du genre objet->release vraimentt plus agréable qu'une lourde ReleaseObjet (objet) ... Je cherche encore le meilleur moyen de l'implémenter, en tout cas je vais vérifier qu'un delete appellé par release ne peut pas avoir d'effet pervers dans mon code ...

Reply

Marsh Posté le 22-10-2001 à 19:17:50    

BENB a écrit a écrit :

 
:??:
peu importe...
 
si tu as alloue ton objet avec new tu le detruis avec delete
si tu as alloue ton abjet avec new[] tu le detruis avec delete[]
il faut simplement que cette instruction soit le derniere de ta fonction Release... et bien sur que cette fonction ne soit pas appellee par une methode de l'objet (ou alors en dernier)
Par contre dans les destructeurs ce ne change rien...  




 
je n'ai jamais dit le contraire, par contre dire ke c'est naturel et sans danger de faire un delete this ds le destructeur, c'est une autre paire de manches (c'est la dessus que je voulais insister).

Reply

Marsh Posté le 22-10-2001 à 19:44:41    

bon et ben voila : j'ai opté pour une fonction globale dans un espace de nom pour ce release, et ce pour plusieurs raisons : déjà en fait ça respecte mieux la logique de programmation vu que je crée avec un fonction globale, donc je détruit de la même manière. Ensuite ça me permet de faire un traitement "after-death" que ne permet pas la 1ere solution. Pis enfin comme ça j'aurais plus peur le soir en m'endormant que ça le delete this cache un mystérieux bug ... ;)
Merci pour vos réponses.

Reply

Marsh Posté le 23-10-2001 à 09:39:29    

freewol
Qu'est-ce que tu entends par "instanciation implicite" ? Moi je trouve très agréable la gestion des interfaces, ça permet d'avoir une grande modularité du code ie très peu de modifs à faire du coté "client" pour obtenir des trucs très différents
Ben par instanciation implicite j´entend justement le "petit new" que l´utilisateur ne controle pas..
C vrai c bien utile d´avoir des interfaces exportées, mais pour ça pas besoin d´instanciation implicite.. Tu peux avoir ta série de classes instanciées normalement qui exportent ttes la/les même/s interfaces.. :)

Reply

Marsh Posté le 23-10-2001 à 09:55:41    

wpk a écrit a écrit :

 
 
je n'ai jamais dit le contraire, par contre dire ke c'est naturel et sans danger de faire un delete this ds le destructeur, c'est une autre paire de manches (c'est la dessus que je voulais insister).  




 
La d'accord...  
mais lui parlais d'un delete this hors du destructeur (il parlait d'une methode Release)...

Reply

Marsh Posté le 23-10-2001 à 09:57:00    

freewol a écrit a écrit :

bon et ben voila : j'ai opté pour une fonction globale dans un espace de nom pour ce release, et ce pour plusieurs raisons : déjà en fait ça respecte mieux la logique de programmation vu que je crée avec un fonction globale, donc je détruit de la même manière. Ensuite ça me permet de faire un traitement "after-death" que ne permet pas la 1ere solution. Pis enfin comme ça j'aurais plus peur le soir en m'endormant que ça le delete this cache un mystérieux bug ... ;)
Merci pour vos réponses.  




Tu me fais peur avec ton traitement "after-death"
A priori si tu peux le faire dans une globale, tu peut le faire dans une methode de l'objet...

Reply

Marsh Posté le 23-10-2001 à 10:00:20    

H4dd3R a écrit a écrit :

freewol
Qu'est-ce que tu entends par "instanciation implicite" ? Moi je trouve très agréable la gestion des interfaces, ça permet d'avoir une grande modularité du code ie très peu de modifs à faire du coté "client" pour obtenir des trucs très différents
Ben par instanciation implicite j´entend justement le "petit new" que l´utilisateur ne controle pas..
C vrai c bien utile d´avoir des interfaces exportées, mais pour ça pas besoin d´instanciation implicite.. Tu peux avoir ta série de classes instanciées normalement qui exportent ttes la/les même/s interfaces.. :)  




 
oui mais avec l'instanciation à la com (qui est d'ailleurs un desing pattern fabrique de classe ou d'objets j'ai oublié un peu tout ça) pas besoin des headers, juste la déclaration de l'interface, et si la classe que tu fais instancier change en taille, pas besoin de recompiler le code client. De plus c'est un principe poo que de séparer le plus possible les classes.

Reply

Marsh Posté le 23-10-2001 à 19:46:06    

BENB a écrit a écrit :

 
Tu me fais peur avec ton traitement "after-death"
A priori si tu peux le faire dans une globale, tu peut le faire dans une methode de l'objet...  




 
Ben non en fait parce que la fonction globale peut accéder à certaines variables et types inaccessibles à ma classe, mais de toute façon pour l'instant je ne fais rien après le delete, je pense que ça me laisse plus libre pour la suite c'est tout.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed