If I delete a class, are its member variables auto

2019-01-21 23:29发布

问题:

I have been researching, and nothing relevant has come up, so I came here.

I am trying to avoid memory leaks, so I am wondering:

Say I have class MyClass with member ints a and b, and an int array c, which are filled in a member function:

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;
} 

Now, after I call delete mc, will a, b, and all the contents of c be deleted as well? Or will I have to do that explicitly in the destructor of MyClass?

回答1:

When delete mc is executed, the compiler calls the destructor of the object (MyClass::~MyClass()) and then deallocates the memory associated with it.

The default destructor (when you don't declare your own) calls the destructors of all member variables, in order from last to first by declaration (that is, in this case, c, then b, then a). Since those members in this example are POD types (they do not have a destructor), no work is done.



回答2:

The rule is very simple: every object created with new must be destroyed exactly once with delete; every array created with new[] must be destroyed exactly once with delete[]; everything else must not be deleted. So your code is correct; you are deleting mc after creating it with new, and not deleting the members which were not created with new.

Applying the rule can be quite tricky when the program flow gets complicated (especially when exceptions are involved); for that reason, it is much better not to delete objects yourself, but to immediately use the result of new to initialise a smart pointer to manage the object for you.



回答3:

Variables inside of a class have class scope and are destroyed when the class is. The only thing you need to worry about is pointers -- those will need to be addressed appropriately in your destructor.



回答4:

Class members are a part of the class' memory structure.

So when you free that memory, the members are freed with it.

NOTE:
If you have pointers they are destroyed too, BUT the memory they point at isn't destroyed.

More about class memory consumption:

C++ Classes



回答5:

For your specific example, the answer is yes. That's because you allocated the member variables on the stack. If you had used new to allocate memory for the member variables the answer would be no and would require you to explicitly delete the member variables in the class' destructor.

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;          
     }     
   } 


} 


回答6:

When you free an object, all of its member variables are automatically freed as well. So, in your case, yes, a, b and c are all freed.

However, if one of your member variables is a pointer, only the pointer itself is automatically freed, not the object it points to - this is the most common case for having to write your own destructor.



回答7:

delete will reclaim the memory that your object contains. If your type maintains pointers to dynamically allocated memory then you will need to clean those up inside of your destructor.

As for your specific quesiton:

after I call delete mc, will a, b, and all the contents of c be deleted as well? Or will I have to do that explicitly in the destructor of MyClass?

They will be cleaned up for you as they were not allocated dynamically.



回答8:

Your three variables were not allocated with new so there would be no need to delete them at all.

They would be destructed when your class is deleted (as they were allocated when your class was newd), but that's not the same as being deleted.