12
votes

Destructeurs en C ++

Le destructeur a-t-il désactivé la mémoire attribuée à l'objet qu'il appartient ou est-il juste appelé afin qu'il puisse effectuer un entretien ménager de dernière minute avant que l'objet ne soit traité par le compilateur?


1 commentaires

Un destructeur doit supprimer tous les objets alloués dynamiquement détenus par l'objet du destructeur, mais le destructeur n'est pas responsable de la libération de la mémoire que son objet réside dans.


6 Réponses :


2
votes

Le destructeur est appelé à permettre à l'objet d'effectuer un nettoyage ainsi que de détruire tout autre objet que l'objet lui-même a créé.

Le système d'exploitation traitera de traiter l'objet lui-même après avoir terminé le destructeur.


0 commentaires

32
votes

Le 'compilateur' ne supprime rien. Il crée un code qui fait des choses à l'exécution.

Lorsque vous écrivez Supprimer quelque chose, code> Le compilateur, en essence, écrit: P>

  if ( has_virtual_destructor( * somePointer  ) ) {
       // virtual dispatch to a compiler-generated function
      dynamic_cast< true_dynamic_type * >(somePointer)->destroy_dynamic_type();
       /* contents of true_dynamic_type::destroy_dynamic_type() {
              this->~true_dynamic_type();
              operator delete( this); // executed within class context
       } */
  } else {
      somePointer->~ClassName();
      operator delete(somePointer);
  }


4 commentaires

C'est beaucoup de upvotes; v) ... peut-être mentionner la distribution à un type de dynamique réel dans le cas d'un destructeur virtuel. (Et, la façon dont l'opérateur Supprimer Works de recherche, Supprimer est en fait appelé à partir d'un destructeur virtuel "en charge". Sans mentionner cela pourrait être déroutant CF une trace de profil .)


@potatoswatter: N'hésitez pas à éditer. Je ne peux pas expliquer le glissement de terrain, je viens de taper l'évidence.


Un mineur Nitpick: Ce si (has_virtual_destructor ... est pas exécuté au moment de l'exécution. Le compilateur peut décider de chaque type (donc seulement sur le < I> Static Type) Que ce soit un destructeur virtuel ou non virtuel et émet un code approprié pour les deux situations. Vous ne savez pas que ce qui se passe lorsque vous essayez de Supprimer A Void * < / Code> Mais je suppose que cela sera UB.


Le compilateur ne fera jamais de moulage dynamique ou de vérifier si la classe a un destructeur virtuel au moment de l'exécution! Le scénario de cas pire prend une adresse relative à la base si l'héritage virtuel est utilisé. Ensuite, cela passe simplement par un circuit équitable et qui est décalé + appel à l'adresse. Si aucun destructeurs virtuels n'est présent, il ne peut rien faire ou appeler le destructeur (ou l'aligner). Mais votre code là-bas est loin d'être de ce qu'il fait ...



0
votes

1) Destructor n'appartient pas à l'objet, il appartient à la classe

2) Il appelle lestructor pour tous les types définis par l'utilisateur (objets de classe) dans sa classe.

3) Le nettoyage est une activité facultative qui est faite uniquement si elle est vraiment requise


0 commentaires

0
votes

La mémoire est distribuée juste après la sortie de la fonction destructeurs et avant que l'exécution ne renvoie à l'appel "Supprimer" ou point dans laquelle une instance d'objet est hors de portée. En théorie, il est possible de configurer un autre gestionnaire de mémoire pour gérer de nouvelles et supprimés, mais ce serait un changement explicite du comportement par défaut.


0 commentaires

0
votes

Plus spécifiquement, personne, mais le programmeur transmet la mémoire en C ++. Si l'objet est sur la pile, il réside dans l'espace mémoire du programme et prend de l'espace pendant la durée de vie du programme. Si c'est sur le tas, quiconque a créé l'objet est responsable de la récitation. Thats ce que suppression fait . Cela nous amène au destructeur - si vous créez des objets de votre classe, le destructeur vous permet de les supprimer lorsque la classe quitte la classe. Cela vous permet de «éteindre les lumières lorsque vous partez».


2 commentaires

Il n'y a pas de "le programmeur". Si je, un programmeur, écrivez une classe avec une variable de membre de type std :: Vecteur, je n'ai pas besoin et ne doit pas écrire de code pour la supprimer. Le compilateur générera automatiquement du code pour appeler le std the STD :: Vecteur Destructor qu'un autre programmeur a écrit quelque part à un moment donné et mis à disposition dans le fichier d'en-tête .


Il y a toujours un "programmeur" même si ce n'est pas précisément, les ordinateurs ne tuent pas les gens, les gens tuent des gens. Ou une mémoire de fuite, peu importe. Si vous créez une variable de membre de std :: vecteur, alors c'est sur la pile. Aucune allocation, aucune responsabilité. Si votre std :: vecteur alloue la mémoire de tas en interne, alors "le programmeur" dans ce cas est le programmeur de std :: vecteur, pas vous, donc vous ne devriez donc pas avoir à vous en soucier.



0
votes

Destructeurs appellent automatiquement les destructeurs des variables de membre de l'objet détruit. Ces destructeurs peuvent ou non libérer de la mémoire. Cependant, un pointeur n'a pas de destructeur, ni si vous préférez, le destructeur du pointeur ne fait rien. Il ne libère pas la mémoire qu'elle pointe. Si un objet contient un pointeur à un objet obtenu à partir de "Nouveau" ou "MALLOC", il appartient au programmeur de cet objet de rendre le destructeur faire la bonne chose. Vous devez programmer votre destructeur à "Supprimer" ou "GRATUIT" la mémoire si elle fait partie de l'objet destructions. Par exemple, un objet "Vector" obtient typiquement la mémoire du tas, car la quantité de mémoire requise n'est généralement pas connue au moment de la compilation. Cette mémoire fait conceptuellement partie de l'objet vectoriel et le programmeur de la classe de vecteur doit donc appeler "Supprimer" sur celui-ci dans le destructeur. Les classes de bibliothèque de modèles standard comme STD :: vecteur le faire correctement.

D'autre part, certains objets contiennent des références à d'autres objets. Un dictionnaire ou un index contiendra des références (pointeurs) sur des objets qui ne les font pas conceptuellement. Cette mémoire ne doit pas être libérée par le destructeur. (Si vous supprimez votre numéro de téléphone de l'annuaire téléphonique, vous ne voulez pas que votre téléphone disparaisse automatiquement.)

Il y a des exceptions que le novice n'a pas besoin d'être concerné au début. L'un est lorsque l'objet et ses conteneurs sont programmés pour utiliser le comptage de référence et l'objet référencé n'est pas vraiment libéré tant que le dernier objet qui l'a fait référence le permet. Une autre exception est en cas de "placement nouveau".


0 commentaires