Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
857 connectés 

  FORUM HardWare.fr
  Programmation

  [C++] question de delete sur une hiérarchie de classe

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C++] question de delete sur une hiérarchie de classe

n°78288
ayachi
Posté le 04-12-2001 à 23:40:37  profilanswer
 

voilà je me suis la tête avec un plantage sur un delete :
d'abord un code exemple du problème
 
class CompteurDeReferences
{
public :
     CompteurDeReferences( );
 ~CompteurDeReferences( ) { };
 void AjouteReference( );
 void Relache( );
private:
 int _MonCompteurDeReferences;
};
 
 
CompteurDeReferences::CompteurDeReferences( )
{
 _MonCompteurDeReferences = 0;
}
 
void CompteurDeReferences::AjouteReference( )  
{  
 ++_MonCompteurDeReferences;  
}
 
void CompteurDeReferences::Relache( )  
{  
 if( --_MonCompteurDeReferences == 0 )
 {
  delete this;
 }
}
 
class A : public CompteurDeReferences
{
public:
 virtual int get( ) { return 5; }
 ~A( ) { }
};
 
void main( )
{
 A* p = new A;
 
 p->AjouteReference( );
 
 p->Relache( );
 
}
 
Sur le delete du Relache le delete se plante.
L'objet A se compose donc au début de la classe CompteurDeReferences puis un pointeur vers la vtable de A.
Et donc dans le delete comme ~CompteurDeReferences n'est pas
virtuel c'est seulement le destructeur de CompteurDeReferences  
qui est appelé et pas celui de A. Bon ok mais alors pourquoi ça plante ? j'arrive pas à comprendre.
Si on met au moins une méthode virtuelle dans CompteurDeReferences ça passe. Quelqu'un a-t-il une idée ?
Je sais que de toute façon dans une hiérarchie faut que la classe la plus haute soit polymorphe mais j'aimerais comprendre quand même pourquoi ça marche pas.
De plus est-ce que lorsque un destructeur est virtuel dans une classe X, n'importe quel destructeur d'une fille de X l'est ?
 
Merci.:)

mood
Publicité
Posté le 04-12-2001 à 23:40:37  profilanswer
 

n°78295
verdoux
And I'm still waiting
Posté le 05-12-2001 à 00:14:17  profilanswer
 

La partie exclusivement A de l'objet n'est pas détruite par le delete this si le destructeur n'est pas virtuel.

n°78320
ayachi
Posté le 05-12-2001 à 05:50:09  profilanswer
 

Verdoux a écrit a écrit :

La partie exclusivement A de l'objet n'est pas détruite par le delete this si le destructeur n'est pas virtuel.  




 
ok ça je le savais mais ce que je ne comprend pas c'est pourquoi ça plante. Si on une méthode virtuelle ( autre que le destructeur ), ça ne plante pas et la partie A n'est pas détruite non plus.

n°78328
El_gringo
Posté le 05-12-2001 à 09:09:59  profilanswer
 

Mais t vraiement sur que ton objet peut se détruire lui même !?
tu crois pas que t plutot obligé de faire direcement un appel au delete de l'instance dans la classe utilisatrice ?
D'ailleur, ce qui serai plus logique, c que le code que tu mets dans Relache, tu le mettes dans ton destructeur, et pif paf, plus de méthode relache. plus d'emmerdements !:D

n°78330
BENB
100% Lux.
Posté le 05-12-2001 à 09:17:39  profilanswer
 

ayachi a écrit a écrit :

 
 
ok ça je le savais mais ce que je ne comprend pas c'est pourquoi ça plante. Si on une méthode virtuelle ( autre que le destructeur ), ça ne plante pas et la partie A n'est pas détruite non plus.  




Ca plante car tu ne detruit pas A mais uniquement Compteur de reference qui est dans A. Ton destructeur doit etre virtuel, pour que la methode puisse marcher...
En effet le delete this doit etre vu comme un appel au destructeur, et la tu appelle le destructer de Compteur de reference uniquement, et pas celui de A...

n°78378
darthguy
Posté le 05-12-2001 à 11:45:10  profilanswer
 

hum...  
Je suis pas certain a 100% mais il me semble quand meme que tu peux pas detruire un objet dans une de ses methodes.
La methode fait partie de l'objet alloue. Si tu liberes la mémoire, au retour de delete, tu te retrouves dans...  
bah en tous cas, tu devrais te retrouver dans la methode. Mais comme l'objet a ete desalloue...

n°78385
clemarch
Posté le 05-12-2001 à 11:58:31  profilanswer
 

Bon ce qu'il faut faire , c'est super simple:
Ta fonction Relache ne doit pas faire un delete mais juste Decrementer le compteur de Référence,
et dans ton main tu dois faire un delete de A pour que l'objet soit desalloué.

n°78409
BENB
100% Lux.
Posté le 05-12-2001 à 13:26:15  profilanswer
 

clemarch > c'est justement ce qu'il ne veut pas faire...
 
darthguy > cela ne pose aucun probleme tant que l'on ne fais plus reference a l'objet...
Le theme de l'objet sucidaire est un grans classique. le delete doit etre la derniere instruction faisant reference a l'objet, ce qui n'est pas si evident que cela avec des methodes polymorphes...

n°78412
youdontcar​e
Posté le 05-12-2001 à 13:30:30  profilanswer
 

darthguy a écrit a écrit :

hum...  
Je suis pas certain a 100% mais il me semble quand meme que tu peux pas detruire un objet dans une de ses methodes.
La methode fait partie de l'objet alloue. Si tu liberes la mémoire, au retour de delete, tu te retrouves dans...  
bah en tous cas, tu devrais te retrouver dans la methode. Mais comme l'objet a ete desalloue...


c'est tout à fait possible, c'est comme ça que marche 3d studio max.

n°78542
ayachi
Posté le 05-12-2001 à 17:41:26  profilanswer
 

darthguy a écrit a écrit :

hum...  
Je suis pas certain a 100% mais il me semble quand meme que tu peux pas detruire un objet dans une de ses methodes.
La methode fait partie de l'objet alloue. Si tu liberes la mémoire, au retour de delete, tu te retrouves dans...  
bah en tous cas, tu devrais te retrouver dans la methode. Mais comme l'objet a ete desalloue...  




 
Bah pour tout le standard COM ( et tous les logiciels qui vont avec IE, windows, DirectX, Office et des milliers d'autres ) c'est comme ça que ça marche, dans la fonction fondamentale
IUnknown::Release( ).
Sinon je reprécise, le fait que le destructeur soit virtuel
n'est pas indispensable pour que ça ne plante pas ( mais indispensable sinon pour bien coder ) mais il faut qu'au moins
une méthode soit virtuelle, et là y'a que le destructeur de Compteur qui est appelé et pas celui de A.
Il faut que je comprenne, je vais y arriver ... :)

mood
Publicité
Posté le 05-12-2001 à 17:41:26  profilanswer
 

n°78555
BENB
100% Lux.
Posté le 05-12-2001 à 17:53:10  profilanswer
 

Mais tu s sur que c'est sur le delete qu'il plante et pas sur le retour du release ?  
Ou meme la fin de ton prog ?
Car logiquement ce que tu as alloue dans ton prog est libere a la fin... donc p est libere et l'est deja a moitier...
 
A propos le but c'est de faire des smart pointer ?

 

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

n°78560
ayachi
Posté le 05-12-2001 à 17:56:42  profilanswer
 

BENB a écrit a écrit :

Mais tu s sur que c'est sur le delete qu'il plante et pas sur le retour du release ?  
Ou meme la fin de ton prog ?
Car logiquement ce que tu as alloue dans ton prog est libere a la fin... donc p est libere et l'est deja a moitier...
 
A propos le but c'est de faire des smart pointer ?  
 
 




 
ouais c'est pour être utilisé avec des smart pointer
Non c'est sur le delete this, certain ( sauf si le debugger m'aurait menti à l'insu de mon plein gré :) )

n°78563
BENB
100% Lux.
Posté le 05-12-2001 à 18:01:42  profilanswer
 

ayachi a écrit a écrit :

 
 
ouais c'est pour être utilisé avec des smart pointer
Non c'est sur le delete this, certain ( sauf si le debugger m'aurait menti à l'insu de mon plein gré :) )  




Pourquoi ne pas utiliser template et procuration plutot ?
Un compteur de reference dans une classe template qui point sur ton type, comme cela plus besoin de cet heritage...
 
Je suis desolee... je ne reponds pas a la question mais a comment faire autrement :D

n°78569
ayachi
Posté le 05-12-2001 à 18:05:18  profilanswer
 

BENB a écrit a écrit :

 
Pourquoi ne pas utiliser template et procuration plutot ?
Un compteur de reference dans une classe template qui point sur ton type, comme cela plus besoin de cet heritage...
 
Je suis desolee... je ne reponds pas a la question mais a comment faire autrement :D  




 
Donnes un bout de code pour voir stp

n°78576
BENB
100% Lux.
Posté le 05-12-2001 à 18:16:09  profilanswer
 

template <class T>
class RefCounter
{
public:
   RefCounter(T&);
   RefCounter(RefCounter<T> );
   ~RefCouneter();
   T& operator*();
   T* operator->();
   IncCounter();
   DecCounter();
private:
   T* Target;
   int Counter
}; // grosso modo...
 
L'intetet c'est qu'ensuite pour chaque classe tu choisit si tu veux un smart pointer ou pas...

 

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


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation

  [C++] question de delete sur une hiérarchie de classe

 

Sujets relatifs
[PHP]-question pour super balez!!!une petite question ?
[JAVA]Applet, question basic :)[C++] question sur les templates
Petite question au sujet de Borland C++ Builder 5.......[PHP] Question super facile :))) Venez !!!
Question en C : Warning à la conpetite question php
Petite question niveau phpUne question ???
Plus de sujets relatifs à : [C++] question de delete sur une hiérarchie de classe


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR