Ne delete sur un pointeur vers une sous-classe d'appeler le destructeur de la classe de base?
J'ai un class A
qui utilise un tas d'allocation de mémoire pour l'un de ses champs. La classe A est instancié et stocké dans un champ de pointeur dans une autre classe (class B
.
Quand je suis fait avec un objet de la classe B, j'appelle delete
, qui, je suppose appelle le destructeur... Mais est-ce l'appel du destructeur de la classe A ainsi?
Edit:
Pour les réponses, je prends ça (merci de modifier si nécessaire):
delete
d'une instance de B appels B::~B();- qui appelle
A::~A();
A::~A
devrait explicitementdelete
tous allouées sur la pile des variables de membre de la Un objet;- Enfin le bloc de mémoire stockage de ladite instance de la classe B est retourné vers le tas quand nouveau a été utilisé, il dispose d'un bloc de mémoire sur le tas, alors invoqué des constructeurs pour l'initialiser, maintenant, après toutes les destructeurs ont été invoquées pour finaliser l'objet le bloc où l'objet résidé est retourné au tas.
Vous devez vous connecter pour publier un commentaire.
Le destructeur de A à exécuter lorsque sa durée de vie est plus. Si vous voulez sa mémoire pour être libérés, et le destructeur de l'exécuter, vous devez le supprimer si il a été alloué sur le tas. Si elle a été alloué sur la pile, cela se fait automatiquement (c'est à dire quand elle est hors de portée; voir RAII). Si c'est un membre d'une classe (et non pas un pointeur, mais un membre à part entière), puis ce sera le cas lorsque l'objet est détruit.
Dans l'exemple ci-dessus, chaque delete et delete[] est nécessaire. Et pas de "supprimer" est nécessaire (ou en effet en mesure d'être utilisé) où je n'ai pas l'utiliser.
auto_ptr
,unique_ptr
etshared_ptr
etc... sont très bien pour faire cette gestion de durée de vie beaucoup plus facile:++
opérateur sur elle. Donc je me demande si le pointeur qui pointe au milieu de la classe de données a encore de l'effet.Lorsque vous appeler delete sur un pointeur alloué par de nouvelles, le destructeur de l'objet pointé sera appelée.
Il est nommé "destructeur", pas "déconstructeur".
À l'intérieur du destructeur de chaque classe, vous devez supprimer toutes les autres variables de membre qui ont été affectés par la nouvelle.
edit: Pour clarifier les choses:
Dire que vous avez
L'allocation d'une instance de B, puis de la suppression est propre, parce que le B alloue à l'interne seront également supprimés dans le destructeur.
Mais les instances de la classe C est une fuite de mémoire, car elle alloue une instance de A qui il ne se relâche pas (dans ce cas C ne dispose même pas d'un destructeur).
Si vous avez un pointeur normal (
A*
) alors que le destructeur ne sera pas appelé (et de mémoire pourA
l'instance ne sera pas libéré soit), à moins que vous nedelete
explicitement dansB
's destructeur. Si vous souhaitez automatique de la destruction de regarder des pointeurs intelligents commeauto_ptr
.Vous devez supprimer Un vous-même dans le destructeur de B.
Lorsque vous faites:
Le destructeur sera appelé uniquement si votre classe de base a le mot clé virtual.
Alors si vous n'avez pas un destructeur virtuel seulement ~B() sera appelée. Mais puisque vous avez un destructeur virtuel, d'abord ~D() sera appelée, ~B().
Pas de membres, de B ou D alloué sur le tas sera libérée, à moins que vous ne les supprimiez. Et la suppression de va appeler leur destructeur aussi.
Je me demandais pourquoi ma classe " destructeur n'a pas été appelé. La raison était que j'avais oublié d'inclure la définition de la classe (#include "de la classe.h"). Je n'avais qu'une déclaration comme "classe A", et le compilateur a été heureux avec elle et laissez-moi appeler "supprimer".
Pas. le pointeur sera supprimé. Vous devez appeler la supprimer sur Un explicite dans le destructeur de B.
Le destructeur de l'objet de classe A sera appelée uniquement si l'option supprimer est appelée pour un objet. Assurez-vous de supprimer le pointeur dans le destructeur de la classe B.
Pour un peu plus d'information sur ce qui se passe lors de la supprimer est appelée sur un objet, voir:
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.9
non il n'y aura pas d'appel au destructeur de classe, vous devez l'appeler explicitement (comme PoweRoy dit), supprimer la ligne "delete ptr;" en exemple pour comparer ...
Vous avez quelque chose comme
Si vous appelez ensuite
delete b;
, rien ne se passe à un, et vous avez une fuite de mémoire. En essayant de se rappeler àdelete b->a;
n'est pas une bonne solution, mais il ya un couple de d'autres.C'est un destructeur de B qui va supprimer un. (Si a est 0, que supprimer ne fait rien. Si a n'est pas 0 mais n'a pas de point à la mémoire de nouveau, vous obtenez tas de corruption.)
De cette façon, vous n'avez pas comme un pointeur, mais plutôt un auto_ptr<> (shared_ptr<> sera de faire aussi bien, ou d'autres pointeurs intelligents), et il est automatiquement supprimé lorsque b est.
De ces manières fonctionne bien, et j'ai utilisé à la fois.