Ask
any programmer, he'll immediately reply saying "A
destructor is a member function of a class, which gets called
when the object goes out of scope". This means all clean
ups and final steps of class destruction are to be done in
destructor. A virtual function is something which helps a
derived class in overriding the implementation of a
functionality of a base class.
The
order of execution of destructor in an inherited class during
a clean up is like this.
1. Derived class destructor
2. Base class destructor
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.
Now
turning our attention to why a destructor has to be virtual,
the reason is that we, programmers are very smart. We'll do
days and nights of work to inherit and extend the
functionality of an existing class which is being used, and
say that we don't want to change the implementation/interface
just for the sake of a new entrant. Let me explain this with
an example.
#include
<iostream.h>
class Base
{
public:
Base(){
cout<<"Constructor: Base"<<endl;}
~Base(){ cout<<"Destructor :
Base"<<endl;}
};
class Derived: public Base
{
//Doing a lot of jobs by extending
the functionality
public:
Derived(){ cout<<"Constructor:
Derived"<<endl;}
~Derived(){ cout<<"Destructor :
Derived"<<endl;}
> };
void main()
{
Base *Var = new
Derived();
delete Var;
}
Try
executing this code, you'll see the difference. To our
observation, the constructors are getting called in the proper
order. But to the dread of a programmer of a large project,
the destructor of the derived class was not called at all.
This is
where the virtual mechanism comes into our rescue. By making
the Base class Destructor virtual, both the destructors will
be called in order. The following is the corrected sample.
#include
<iostream.h>
class Base
{
public:
Base(){
cout<<"Constructor: Base"<<endl;}
virtual
~Base(){ cout<<"Destructor :
Base"<<endl;}
};
class Derived: public Base
{
//Doing a lot of jobs by extending
the functionality
public:
Derived(){ cout<<"Constructor:
Derived"<<endl;}
~Derived(){ cout<<"Destructor :
Derived"<<endl;}
};
void main()
{
Base *Var = new
Derived();
delete Var;
}
Note:
There is one more point to be noted regarding virtual
destructor. We can't declare pure virtual destructor. Even if
a virtual destructor is declared as pure, it will have to
implement an empty body (at least) for the destructor.