Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why base class destructor (virtual) is called when a derived class object is deleted?

A difference between a destructor (of course also the constructor) and other member functions is that, if a regular member function has a body at the derived class, only the version at Derived class gets executed. Whereas in case of destructors, both derived as well as base class versions get executed?

It will be great to know what exactly happens in case of destructor (maybe virtual) & constructor, that they are called for all its base classes even if the most derived class object is deleted.

Thanks in advance!

like image 562
KedarX Avatar asked Jul 16 '10 03:07

KedarX


People also ask

Why does a destructor in base class need to be declared virtual?

A virtual destructor is needed when you delete an object whose dynamic type is DerivedClass by a pointer that has type BaseClass* . The virtual makes the compiler associate information in the object making it able to execute the derived class destructor. Missing the virtual in such case causes undefined behavior.

Why destructor is used when delete is there?

When delete is used to deallocate memory for a C++ class object, the object's destructor is called before the object's memory is deallocated (if the object has a destructor). If the operand to the delete operator is a modifiable l-value, its value is undefined after the object is deleted.

What will happen when a base class pointer is used to delete the derived object?

Deleting a derived class object using a pointer of base class type that has a non-virtual destructor results in undefined behavior. To correct this situation, the base class should be defined with a virtual destructor. For example, following program results in undefined behavior.

Does derived destructor call base destructor?

A derived class's destructor (whether or not you explicitly define one) automagically invokes the destructors for base class subobjects. Base classes are destructed after member objects.


1 Answers

The Standard says

After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X’s direct non-variant members,the destructors for X’s direct base classes and, if X is the type of the most derived class (12.6.2), its destructor calls the destructors for X’s virtual base classes. All destructors are called as if they were referenced with a qualified name, that is, ignoring any possible virtual overriding destructors in more derived classes. Bases and members are destroyed in the reverse order of the completion of their constructor (see 12.6.2). A return statement (6.6.3) in a destructor might not directly return to the caller; before transferring control to the caller, the destructors for the members and bases are called. Destructors for elements of an array are called in reverse order of their construction (see 12.6).

Also as per RAII resources need to be tied to the lifespan of suitable objects and the destructors of respective classes must be called upon to release the resources.

For example the following code leaks memory.

 struct Base  {        int *p;         Base():p(new int){}        ~Base(){ delete p; } //has to be virtual  };   struct Derived :Base  {        int *d;        Derived():Base(),d(new int){}        ~Derived(){delete d;}  };   int main()  {      Base *base=new Derived();      //do something       delete base;   //Oops!! ~Base() gets called(=>Memory Leak).  } 
like image 64
Prasoon Saurav Avatar answered Oct 13 '22 01:10

Prasoon Saurav