Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is base-class destructor called on derived object when destructor of derived class is non-virtual?

Why are all destructors, ~D(),~C(),~B(),~A() being called in the example below?

There is only one virtual destructor: that of A.

Here is the code:

#include<iostream>
using namespace std;

class A
{
public:
  virtual ~A()
  {
    cout<<"destruct A\n";
  }

};
class B:public A
{
public:
  ~B()
  {
  cout<<"destruct B\n"; 
  }
};
class C:public B
{
public:
  ~C()
  {
    cout<<"destruct C\n";
  }
};
class D:public C
{
public:
   ~D()
   {
     cout<<"destruct D\n"; 
   }
};

int main()
{
    A* ptr = new D();
    delete ptr;
    return 0;
}
like image 491
EmptyData Avatar asked Oct 17 '12 05:10

EmptyData


People also ask

What happens if base class destructor is not virtual?

Deleting a derived class object using a pointer of base class type that has a non-virtual destructor 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.

Why does base class need virtual destructor?

Virtual destructors in C++ are used to avoid memory leaks especially when your class contains unmanaged code, i.e., contains pointers or object handles to files, databases or other external objects.

Does derived class destructor need to be virtual?

If you want to call a derived class function when all you have is a base class pointer/reference, that function must be declared virtual .


2 Answers

Once A's destructor is declared virtual, the destructors of all derived classes are also virtual, even if they aren't explicitly declared as such.. So the behaviour you see is exactly what is expected

like image 59
juanchopanza Avatar answered Nov 05 '22 04:11

juanchopanza


The destruction order in derived objects goes in exactly the reverse order of construction: first the destructors of the most derived classes are called and then the destructor of the base classes.

A destructor can be defined as virtual or even pure virtual. You would use a virtual destructor if you ever expect a derived class to be destroyed through a pointer to the base class. This will ensure that the destructor of the most derived classes will get called:

A* b1 = new B;//if A has a virtual destructor
delete b1;//invokes B's destructor and then A's

A* b1 = new B;//if A has no virtual destructor
    delete b1;//invokes A's destructor ONLY

If A does not have a virtual destructor, deleting b1 through a pointer of type A will merely invoke A's destructor. To enforce the calling of B's destructor in this case we must have specified A's destructor as virtual:

virtual ~A();

REFERENCE

like image 27
Anirudha Avatar answered Nov 05 '22 05:11

Anirudha