11
votes

Combien fait le destructeur par défaut

Le destructeur par défaut des classes de C ++ est-il automatiquement supprimé des membres qui ne sont pas explicitement attribués en code? Par exemple:

class C {
  public:
    C() {}
    int arr[100];
};

int main(void) {
  C* myC = new C();
  delete myC;
  return 0;
}


2 commentaires

Parasht.com/c++-faq-lite/dtors.html


Il supprime le tableau automatiquement.


5 Réponses :


9
votes

Le constructeur (en l'absence de tout CORT-Initizer-List ) appelle le constructeur par défaut pour chaque sous-boje.

Puisque vous n'avez pas de classes de base et que vos variables de membre sont des types primitifs, cela ne fera rien du tout.

même avec le destructeur. Le vôtre est implicitement généré depuis que vous n'avez pas déclaré un, et cela appellera le destructeur pour chaque sous-boje. Encore une fois, c'est trivial parce que votre seul sous-boje est un agrégat de primitives.

Maintenant, toute la mémoire de la classe sera libérée lorsque vous le supprimez. Étant donné que le tableau est intégré à l'intérieur de la classe, cela fait partie de la même région de mémoire et sera libéré en même temps.


3 commentaires

@Mark: Il n'y a pas de distinction «par défaut» pour les destructeurs, car elles ne peuvent pas être surchargées.


Par "sous-boje", vous voulez dire "membre de données", sûrement?


@Karl: Les sous-observations sont disponibles en deux arômes: les sous-objectifs de la base et les sous-coordonnées des membres de données, et je veux dire les deux. N'avais-je pas mentionné la possibilité de classes de base assez clairement dans ma réponse?



6
votes

Le destructeur défini implicitement (par défaut) appellera le destructeur de chaque membre. Dans le cas d'une matrice de membre, il appellera le destructeur pour chaque élément du tableau.

Notez que les pointeurs n'ont pas de destructeurs; Vous devez les supprimer manuellement. Vous n'avez pas ce problème dans l'exemple fourni, mais c'est quelque chose à être au courant.


7 commentaires

Les pointeurs ont un type de destructeurs (voir ici) , bien que évidemment, ils ne suppriment pas ce qu'ils ne suppriment.


Attendez ... Vous dites que les pointeurs n'ont pas de destructeurs, mais je pensais que Supprimer ne prend qu'un pointeur. Vous dites que le destructeur par défaut appellerait-il supprimer tous les 100 INT dans le tableau?


@Robz, non - je dis - je dis que le destructeur implicite n'appelle pas appelle Supprimer, vous devez le faire vous-même dans un destructeur explicite si vous avez des pointeurs bruts en tant que membres.


Supprimer ne fonctionne que sur les pointeurs. Les 100 int de cette classe seront détruits, via int :: ~ int (int () , pas via Supprimer . Et int :: ~ int () ne fait rien du tout, c'est trivial, tout comme tous les types primitifs (y compris les pointeurs).


@Pubby, les pointeurs n'ont pas de destructeurs - ils appellent destructeurs quand ils sont supprimés. Chose différente tout à fait.


@Benvoigt, 100% correct. Encore meilleur, le compilateur se rendra compte que int :: ~ int () est vide et ne génère aucun code pour cela.


@Mark: Je pense que le public dit que les types de pointeur (primitif ordinaire) ont des destructeurs de la même manière que int :: ~ int () existe - pour permettre de rédiger un code de modèle avec destructeurs explicites Appels (penser à std :: vecteur :: redimensionnement () . Mais les destructeurs des types de pointeur ne font rien, et tout comme vous l'avez dit sur int :: ~ int () < / Code>, le compilateur sait que et ne générera pas d'appel de la fonction.



5
votes

Si votre classe / structure contient un pointeur et que vous allouez explicitement quelque chose pour ce pointeur pour vous reporter, vous devez normalement écrire un correspondant code> dans le DTOR. Les membres qui sont directement incorporés dans la classe / la structure seront créés et détruits automatiquement.

class X { 
    int x; 
    int *y;
public:
    X() : y(new int) {}
    ~X() : { delete y; }    
};


2 commentaires

x :: y est détruit automatiquement. C'est * (x :: y) qui fuit si ce n'était pas pour le destructeur. (Et votre échantillon enfreint la règle de trois / quatre / cinq)


@Benvoigt: Oui - La question était de savoir ce que le destructeur ne fait pas comment écrire une classe qui gère correctement la propriété à distance.



0
votes

Tout ce que vous appelez nouveau pour DOIT avoir une suppression correspondante. Si vous n'avez pas appelé de nouveau pour créer une instance de quelque chose, vous n'avez pas à appeler Supprimer.


1 commentaires

IMHO, vous devriez rarement Supprimer tout dans le code d'application. Au lieu de cela, essayez d'établir une appropriation stricte ou un membre de la sémantique pour tous les membres, de telle sorte que la destruction automatique fait l'affaire. Devrait-il échouer, les pointeurs intelligents sont souvent une meilleure alternative aux pointeurs manuels et Supprimer .



-2
votes

Vous n'êtes pas obligé d'écrire un destructeur. La classe C ++ a le destructeur par défaut de supprimer l'objet après "renvoyer 0" pour recycler la mémoire.


0 commentaires