J'ai un class A
qui utilise une allocation de mémoire de tas pour l'un de ses champs. La classe A est instanciée et stockée en tant que champ de pointeur dans une autre classe ( class B
.
Quand j'en ai fini avec un objet de classe B, j'appelle delete
, ce que je suppose appelle le destructeur ... Mais cela appelle-t-il aussi le destructeur de classe A?
Éditer:
D'après les réponses, je prends cela (veuillez modifier si incorrect):
delete
d'une instance de B appelle B :: ~ B ();- qui appelle
A::~A();
A::~A
devrait explicitementdelete
toutes les variables membres allouées au tas de l'objet A;- Enfin, le bloc de mémoire stockant ladite instance de la classe B est retourné au tas - quand new a été utilisé, il a d'abord alloué un bloc de mémoire sur le tas, puis a appelé des constructeurs pour l'initialiser, maintenant après que tous les destructeurs ont été appelés pour finaliser l'objet, le bloc où résidait l'objet est renvoyé dans le tas.
la source
++
opérateur dessus. Je me demande donc si le pointeur qui pointe au milieu des données de classe a toujours l'effet.Lorsque vous appelez delete sur un pointeur alloué par new, le destructeur de l'objet pointé sera appelé.
la source
Il est nommé "destructeur", pas "déconstructeur".
Dans le destructeur de chaque classe, vous devez supprimer toutes les autres variables membres qui ont été allouées avec new.
edit: Pour clarifier:
Dis que tu as
L'allocation d'une instance de B, puis la suppression est propre, car ce que B alloue en interne sera également supprimé dans le destructeur.
Mais les instances de la classe C perdront de la mémoire, car elle alloue une instance de A qu'elle ne libère pas (dans ce cas, C n'a même pas de destructeur).
la source
Si vous avez un pointeur habituel (
A*
) alors le destructeur ne sera pas appelé (et la mémoire parA
exemple ne sera pas libérée non plus) à moins que vous nedelete
le fassiez explicitement dansB
le destructeur de. Si vous voulez une destruction automatique, regardez des pointeurs intelligents commeauto_ptr
.la source
Vous devez supprimer A vous-même dans le destructeur de B.
la source
Quand vous faites:
Le destructeur ne sera appelé que si votre classe de base a le mot-clé virtual.
Ensuite, si vous n'aviez pas de destructeur virtuel, seul ~ B () serait appelé. Mais puisque vous avez un destructeur virtuel, d'abord ~ D () sera appelé, puis ~ B ().
Aucun membre de B ou D alloué sur le tas ne sera désalloué à moins que vous ne les supprimiez explicitement. Et les supprimer appellera également leur destructeur.
la source
Vous avez quelque chose comme
Si vous appelez ensuite
delete b;
, rien ne se passe à a et vous avez une fuite de mémoire. Essayer de s'en souvenirdelete b->a;
n'est pas une bonne solution, mais il y en a quelques autres.Il s'agit d'un destructeur pour B qui supprimera un fichier. (Si a vaut 0, cette suppression ne fait rien. Si a n'est pas 0 mais ne pointe pas vers la mémoire depuis new, vous obtenez une corruption du tas.)
De cette façon, vous n'avez pas a comme pointeur, mais plutôt un auto_ptr <> (shared_ptr <> fera également l'affaire, ou d'autres pointeurs intelligents), et il est automatiquement supprimé lorsque b l'est.
L'une ou l'autre de ces méthodes fonctionne bien, et j'ai utilisé les deux.
la source
Je me demandais pourquoi le destructeur de ma classe n'était pas appelé. La raison en était que j'avais oublié d'inclure la définition de cette classe (#include "class.h"). Je n'avais qu'une déclaration comme "classe A"; et le compilateur en était satisfait et permettez-moi d'appeler "supprimer".
la source
Non, le pointeur sera supprimé. Vous devez appeler la suppression sur A explicite dans le destructeur de B.
la source
Le destructeur de l'objet de classe A ne sera appelé que si delete est appelé pour cet objet. Assurez-vous de supprimer ce pointeur dans le destructeur de la classe B.
Pour un peu plus d'informations sur ce qui se passe lorsque la suppression est appelée sur un objet, voir: http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.9
la source
non, il n'appellera pas le destructeur pour la classe A, vous devriez l'appeler explicitement (comme PoweRoy l'a dit), supprimez la ligne 'delete ptr;' en exemple pour comparer ...
la source