Incomprehension appels destructeurs et vector… - C++ - Programmation
Marsh Posté le 11-07-2007 à 12:46:04
Salut,
Quand tu places un objet dans un vector, il y a le constructeur par copie qui est appellé, du coup, il est instancié au moins 2 fois. Ensuite le vector va réallouer son tableau pour faire de la place, d'où l'appel de plusieurs destructeurs.
Edit: ces réallocations générant d'autres instances créées par copie, mais comme tu ne traces pas cette instanciation, tu ne le sais pas; ajoute un constructeur par copie et tu verras mieux ce qu'il se passe
Marsh Posté le 11-07-2007 à 12:48:40
Le C++ est un peu loin pour moi mais je pense que ça a à voir avec le constructeur par recopie et le fait que tu stocke tes objets par valeur.
J'espère ne pas avoir dit de conneries.
Edit :
Marsh Posté le 11-07-2007 à 14:30:57
Merci beaucoup, c 'est nettement plus clair !
Après avoir rajouté des traces dans le constructeur par copie, tout est devenu plus limpide.
Un appel à celui-ci est effectué avant chaque push_back.
Vous avez doublement raison, lors des resize du vecteur on se retrouve à recopier les membres du vecteur, et à construire de nouvelles copies !
En disant au vecteur du départ que sa taille va être de 5 (et donc en évitant le mécanisme de resize et donc de recopie) on tombe sur un comportement beaucoup plus compréhensible, avec appels aux destructeurs des objets "initiaux", puis copie de ceux-ci lorsqu'ils sont ajoutés, et enfin destruction de tout le monde lorsque le vecteur sort du scope.
C'est un peu déstabilisant de voir qu'il copie à chaque insertion, naïvement j'imaginais un compteur du nombre de réferences, ou un truc dans ce goût là...Déstabilisant aussi que le resize oblige à réinstancier tout le monde
Mais en tout cas le comportement est plus clair ! Merci beaucoup
J'imagine que la morale que je dois en tirer c'est qu'il vaut mieux gérer soit même les désallocations, en ne stockant que des pointeurs...histoire d'éviter des tonnes d'instanciation et de destruction...
Marsh Posté le 11-07-2007 à 14:33:10
De préférence des boost::shared_ptr, tu auras le comportement que tu as attend au niveau d'un compteur de référence
Marsh Posté le 11-07-2007 à 18:29:54
chalumeau a écrit : [...] Dans un élan de lucidité, je me décide à tester l'air de rien ce comportement, avant de ravager du vrai code... [...] |
Ca change des "bonjour je compran pas pourquoi ma methode WfGet3DObject faire un segmentation core sous Borland 5.2 kan je veux fer mon projet avec la librairie trucmuche, sympa de m'aidé svp ça uuurge !"
(Désolé pour l'inutilité totale de ce message)
Marsh Posté le 11-07-2007 à 18:36:46
Reply
Marsh Posté le 11-07-2007 à 12:03:15
Bonjour, j'ai beaucoup de mal à comprendre l'ordre d'appel des destructeurs pour des objets insérés dans des vecteurs.
Le comportement est limpide quand je stocke des pointeur sur mes objets (je suis responsable explicitement des libérations), mais si je stocke des objets eux même...
Je pensais que lorsque j'instanciais un objet, via
, la durée de vie de l'instance était gérée automatiquement (appel au destructeur lorsque je sors du scope de définition).
Maintenant, j'ai envie de mettre un de mes objets dans un vecteur...Il me semblait que l'appel au destructeur devenait de la résponsabilité du vecteur...Si je retire l'objet, ou si je vide le vecteurs j'imaginais que les destructeurs seraient appellés.
Dans un élan de lucidité, je me décide à tester l'air de rien ce comportement, avant de ravager du vrai code...
Et là c'est le drame.
De mon main, j'appelle une méthode qui instancie 5 objets Truc, et qui les place dans un vecteur.
Les trucs ne sont définis que dans le scope d'une boucle, le vecteur pour toute la fonction.
Je compte bien 5 appels aux constructeurs.
Je compte heu...des tonnes d'appels aux destructeurs...
Alors je vois bien que je m'y prends mal, et que je ferrais mieux de stocker des pointeurs...mais quand même...une ame génereuse pourrait-elle m'expliquer le comportement que j'observe ?
Ce que ca fait lorsque c'est executé (Linux, Windows même combat):
Début Tableau
0
Constructeur 0
Destructeur 0
1
Constructeur 1
Destructeur 0
Destructeur 1
2
Constructeur 2
Destructeur 0
Destructeur 1
Destructeur 2
3
Constructeur 3
Destructeur 3
4
Constructeur 4
Destructeur 0
Destructeur 1
Destructeur 2
Destructeur 3
Destructeur 4
Fin Tableau
Destructeur 0
Destructeur 1
Destructeur 2
Destructeur 3
Destructeur 4
Fini