web-dev-qa-db-fra.com

Si je supprime une classe, ses variables membres sont-elles supprimées automatiquement?

J'ai fait des recherches, et rien de pertinent n'est venu, alors je suis venu ici.

J'essaie d'éviter les fuites de mémoire, alors je me demande:

Disons que j'ai la classe MyClass avec le membre ints a et b, et un int array c, qui sont remplis dans une fonction membre:

class MyClass
{
    public:
        int a, b;
        int c[2];
        void setVariables() 
        {
            a, b = 0;
            for (int i = 0; i < 2; i++) 
            {
                c[i] = 3;
            }
        }
};
int main(int argc, char* argv[])
{
    MyClass* mc = new MyClass();
    mc->setVariables();
    delete mc;
} 

Maintenant, après avoir appelé delete mc, a, b et tout le contenu de c seront-ils également supprimés? Ou devrai-je le faire explicitement dans le destructeur de MyClass?

27
Keelx

Lorsque delete mc Est exécuté, le compilateur appelle le destructeur de l'objet (MyClass::~MyClass()) puis libère la mémoire qui lui est associée.

Le destructeur par défaut (lorsque vous ne déclarez pas le vôtre) appelle les destructeurs de toutes les variables membres, dans l'ordre de la dernière à la première par déclaration (c'est-à-dire, dans ce cas, c, puis b, puis a). Étant donné que les membres de cet exemple sont types POD (ils n'ont pas de destructeur), aucun travail n'est effectué.

29
greyfade

La règle est très simple: chaque objet créé avec new doit être détruit exactement une fois avec delete; chaque tableau créé avec new[] doit être détruit une seule fois avec delete[]; tout le reste ne doit pas être supprimé. Votre code est donc correct; vous supprimez mc après l'avoir créé avec new, et vous ne supprimez pas les membres qui n'ont pas été créés avec new.

L'application de la règle peut être assez délicate lorsque le déroulement du programme se complique (en particulier lorsque des exceptions sont impliquées); pour cette raison, il est préférable de ne pas supprimer les objets vous-même, mais d'utiliser immédiatement le résultat de new pour initialiser un pointeur intelligent pour gérer l'objet pour vous.

33
Mike Seymour

Les membres de la classe font partie de la structure de la mémoire de la classe.

Ainsi, lorsque vous libérez cette mémoire, les membres en sont libérés.

REMARQUE:
Si vous avez des pointeurs, ils sont également détruits [~ # ~] mais [~ # ~] la mémoire vers laquelle ils pointent n'est pas ' t détruit.

En savoir plus sur la consommation de mémoire de classe:

Classes C++

6
Yochai Timmer

Les variables à l'intérieur d'une classe ont une portée de classe et sont détruites lorsque la classe l'est. La seule chose dont vous devez vous soucier est les pointeurs - ceux-ci devront être traités de manière appropriée dans votre destructeur.

4
wanovak

Pour votre exemple spécifique, la réponse est oui. C'est parce que vous avez alloué les variables membres sur la pile. Si vous aviez utilisé new pour allouer de la mémoire aux variables membres, la réponse serait non et vous obligerait à supprimer explicitement les variables membres dans le destructeur de la classe.

class MyClass(): heapVariabl(NULL)
{  
   MyClass()
   {}

   ~MyClass()
   {
     delete heapVariable; 
   }   

   int a, b;     
   int[2] c;     
   int *heapVariable;
   void setVariables()      
   {         
     a, b = 0;       
     heapVariable = new int; // <- requires deletion in destructor to free memory
     *heapVariable = 0;
     for (int i = 0; i < 2; i++)          
     {             
       c[i] = 3;          
     }     
   } 


} 
4
nathan

Lorsque vous libérez un objet, toutes ses variables membres sont également automatiquement libérées. Donc, dans votre cas, oui, a, b et c sont tous libérés.

Cependant, si l'une de vos variables membres est un pointeur, seul le pointeur lui-même est automatiquement libéré, pas l'objet vers lequel il pointe - c'est le cas le plus courant pour avoir à écrire votre propre destructeur.

3
HighCommander4

delete récupérera la mémoire que contient votre objet. Si votre type maintient des pointeurs vers la mémoire allouée dynamiquement, vous devrez nettoyer ceux-ci à l'intérieur de votre destructeur.

Quant à votre question spécifique:

après avoir appelé delete mc, a, b et tout le contenu de c seront-ils également supprimés? Ou devrai-je le faire explicitement dans le destructeur de MyClass?

Ils seront nettoyés pour vous car ils n'ont pas été alloués dynamiquement.

1
Ed S.

Vos trois variables n'ont pas été allouées avec new, il ne serait donc pas nécessaire de les supprimer du tout.

Ils serait être détruits lorsque votre classe est deleted (comme ils ont été alloués lorsque votre classe était newd), mais ce n'est pas la même chose que d'être supprimé.

1
Mark B