Se connecter / S'enregistrer

Résolu Plus de précision sur les destructeurs

Solutions (13)
Tags :
  • precision
  • Mémoires
  • Programmation
, Programmation (collector) |
bonjours a tous, je fais appelle a vous car j'ai une petite incompréhension concernant les destructeurs.
C'est que je ne sais pas ce qu'il faut exactement mettre dedans.
Je m'explique : - faut t'il mettre dedans, les elements qui permettent de detruire les objets qu'on a alloué dynamiquement dans le constructeur ou bien on peut mettre tout les elements qui permettent de detruire les objet qu'on a alloué dynamiquement dans le constructeur et méthodes etc ...

En voici une illustration :
- j'ai une classe qui s'appelle laPageAccueil avec comme méthode afficher le choix dans lequel je fais un new :
  1. void laPageAccueil::afficherLeChoix(QString choix)
  2. {
  3. if (choix.compare("livre")== 0)
  4. {
  5. leLivre *unLivre = new leLivre(this);
  6. unLivre->exec();
  7. delete unLivre;
  8.  
  9. }


comme vous pouvez le voir je fais par la suite un delete. Mais je sais pas si il faut faire un delete dans cette methode, si il faut enlever le delete ou pas car a la fin de la méthode je ne sais pas si il y aura une fuite de mémoire ou si il y aura un delete de la part du compilateur ou bien si il faut faire le delete dans le destructeur de la classe.

J'ai vraiment du mal a expliquer mon incompréhension mais j'ai fait du mieux que j'ai pu si vous ne voyez pas ce que je veux dire je peux vous le re expliquer d'une autre façon.

J'espere que vous me repondrez assez vite :)  en tout cas merci a tous
Contenus similaires
Meilleure solution
partage
|
Quand tu instancies dynamiquement un objet de classe livre, le but est, généralement, de garder son pointeur (qui n'est qu'une adresse mémoire) pour pouvoir le manipuler ailleurs que dans le constructeur. Donc la zone mémoire donc restée allouée toute la vie de l'objet de classe x (l'objet livre reste existant toute la vie de l'objet x).
Si, dans ton constructeur (ou une autre méthode), tu instancies un objet dynamiquement, mais que tu définis le pointeur en local, alors dans ton constructeur (ou méthode), l'objet créé va rester en mémoire (tant que le delete sur l'objet n'est pas appelé). Par contre, ton pointeur qui n'est d'une adresse mémoire va être perdue à la fin du constructeur. Donc, après ton constructeur, tu auras créé un objet de classe livre quelque part en mémoire, mais tu ne saura plus comment le retrouver, et donc tu ne pourras plus faire de delete dessus (ce qui n'est pas bon).
Pour supprimer l'objet, il te faut lui donner son adresse mémoire (bref, un pointeur sur ton objet). En conservant cette adresse mémoire dans l'objet (en passant par une variable membre de la classe), tu pourras y accéder n'importe où dans ton objet, et plus particulièrement dans le destructeur ou tu libèreras la zone mémoire que ton objet occupe.
Si tu instancie un objet que tu veux utiliser seulement dans une méthode, déjà pas besoin de passer par une instanciation dynamique, ou tu peux faire un delete dans la même méthode (avant de perdre l'adresse mémoire). Dans ce cas, la zone mémoire est réservé et libérée dans la méthode. Donc, tu n'as pas besoin de libérer une zone déjà libérée lors de l'appel au destructeur.

Donc, il faut toujours penser à:
1. conserver les adresses mémoire pour pouvoir retrouver les sous-objets en mémoire pour les supprimer
2. supprimer les sous-objets résidents dans l'objet lors du constructeurs.

Enfin, un delete fait appel au destructeur de l'objet, ainsi, si tu as pleins d'objets instanciés en cascade, supprimer l'objet principal permet, via tous les destructeurs, de libérer toutes les zones mémoires lié à l'objet et tous ces sous-objets.
  • Commenter cette solution |
Score
0
òh
òi
, Programmation (collector) |
Meilleure réponse sélectionnée par wahhh.
  • Commenter cette réponse |
Score
0
òh
òi
, Programmation (collector) |
merci a vous deux pour vos explications, tout est clair maintenant, c'est tellement logique que je sais meme pas comment j'ai fait pour ne pas comprendre.
Enfin bon on peut pas tout comprendre du premier coup.
Merci a vous !
  • Commenter cette réponse |
Score
0
òh
òi
, Programmation (collector) |
j'ai pas tres bien compris la partie "ps" pourrait tu developper un peu plus s'il te plait ?
En faisant delete sur unLivre je libere bien la mémoire occupé par l'objet sur lequel pointe unLivre nan ?
  • Commenter cette réponse |
Score
0
òh
òi
|
Faire un delete sur un pointeur non alloué, provoque une exception, car l'adresse contenu dans la variable non allouée est soit nulle, soit une valeur hors zone.

Une bonne méthode est de toujours tout initialiser avec un pointeur NULL dans le constructeur, et de tester si le pointeur est NULL:
  1. x() : livre(0), cahier(0)
  2. {
  3. livre *unLivre = new livre();
  4. }
  5.  
  6. ~x()
  7. {
  8. if( livre )
  9. delete livre;
  10. if( cahier )
  11. delete cahier;
  12. }

ps: dans l'exemple unLivre n'est jamais désalloué (memory leak), donc il faut utiliser une variable membre (par exemple "livre") pour pouvoir libérer la mémoire dans le destructeur.
  • Commenter cette réponse |
Score
0
òh
òi
, Programmation (collector) |
ok j'essaye et je te tiens au courant ^^
  • Commenter cette réponse |
Score
0
òh
òi
, Modérateur |
Je pense pas que ça pose un problème, mais le plus simple est de tester :) 
  • Commenter cette réponse |
Score
0
òh
òi
, Programmation (collector) |
ah oui effectivement, j'avais pas fais gaffe, j'appelle le destructeur de la classe leLivre étant donné que l'objet que je creer dynamiquement sort "du moule" de la classe leLivre :) 

j'ai une autre question :

si par exemple j'ai 3 classes (livre , cahier et X par exemple) et que dans le destructeur de X j'ai ceci :

  1. ~x()
  2. {
  3. delete livre;
  4. delete cahier;
  5. }


mais que dans le constructeur de l'objet X je n'ai alloué dynamiquement qu'un seul objet comme ceci :
  1. x()
  2. {
  3. livre *unLivre = new livre();
  4. }


et que plus tard j'appelle le destructeur :
-cela va t'il poser probleme car je n'ai pas fait d'allocation dynamique pour cahier ?
- le programme va t'il supprimer une information quelconque dans la mémoire et donc faire planter le programme a cause du "delete cahier" ?

voila, merci, j'espere avoir été clair

  • Commenter cette réponse |
Score
0
òh
òi
, Modérateur |
Ce que je veux te dire, c'est que dans ton code au-dessus.
Quand tu vas appeler delete unLivre, ça ne va pas appeler le destructeur de la classe laPageAccueil, mais celui de la classe leLivre

Et je ne suis pas sûr que c'était très clair pour toi ça.
  • Commenter cette réponse |
Score
0
òh
òi
, Programmation (collector) |
ah bon, je croyais parce que j'ai vu un exemple (celui ci) :
  1. Le destructeur Fred::~Fred() va être appelé automatiquement quand vous utiliserez delete
  2.  
  3. delete p; // p->~Fred() est appelé automatiquement


ou on voit bien que quand on fait un delete sur un objet alloué dynamiquement, le compilo remplace ce delete par le destructeur de la classe.
...
Donc toi tu dit que quand on fait un delete on appelle pas le destructeur de la classe, dans ce cas, on fait comment pour l'appeler, doit-on le mettre explicitement ?
  • Commenter cette réponse |
Score
0
òh
òi
, Modérateur |
euh, en faisant delete tu appelle pas le destructeur de la classe courante
  • Commenter cette réponse |
Score
0
òh
òi
, Programmation (collector) |
d'accord donc si j'ai bien compris je peux alloué dynamiquement dans une méthode et faire appelle au destructeur (via un delete) dans cette même méthode à partir du moment ou l'objet en question ce trouve comme attribut dans une classe.
C'est bien sa ?
  • Commenter cette réponse |
Score
0
òh
òi
, Modérateur |
Salut,

Dans le destructeur tu peux mettre ce qui a été alloué dans le constructeur et les méthodes. Mais il faut que la portée de ton objet alloué ne soit pas limité à la méthode, il faut que ce soit un champ de ta classe quoi.

Dans ton cas, tu créé une variable dans ta méthode, donc tu ne pourras plus y accéder dans le destructeur.
Et si tu n'en as plus besoin tout de suite après, tu peux la supprimer directement.
  • Commenter cette réponse |

Ce n'est pas ce que vous cherchiez ?

Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS