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;
}
Deleting a derived class object using a pointer of base class type that has a non-virtual destructor results in undefined behavior.
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.
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.
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 .
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With