virtual destructor is used, so that while deleting the pointer to a base class but pointing to a base class invokes the Derived classes destructor first, then the base classes destrcutore. Hence preventing a memory leak.
The virtual destructor has the same purpose as a virtual function. At runtime looking at the type of object referred by a pointer or reference it is decided which destructor to call -- the destructor of the base class or the destructor of the derived class.
For example, suppose B is a base class and D is a class derived from B and suppose both classes have declared their destrcutor as virtual. Suppose a pointer B *ptr is initialized as follows:
B *ptr = new D();
Now the ptr is of type B* but points to an object of D. So when this object is freed or goes out of scope D's destructor will be called since the destructors have been declared as virtual.
Ref: http://cpptips.hyperformix.com/cpptips/why_virt_dtorFolks: Using virtual destructors is very very important. You need anextremely good reason for not using one.There are three reasons to use virtual destructors.1. Without a virtual destructor, the proper destructor may not becalled:struct B {~B();};struct D : B {~D();};B* b = new D;delete b; // <--------- Will not call D::~D() !!!!!2. Without a virtual destructor, operator delete(void*, size_t) maynot be called with the correct size.struct B {~B(); operator delete(void*, size_t);};struct D : B {~D();};B* b = new D;delete b; // <--------- Will call operator delete(void*, size_t) with // the size of B not the size of D!!!3. Without a virtual destructor, and when MI is used, operatordelete(void*) or operator delete (void*, size_t) may be called withthe wrong address.struct B {~B();};struct A {};struct D : A, B {~D();};B* b = new D;delete b; // <--------- May not pass to operator delete the address // that was returned by operator new!!!All of these conditions are very deadly. It does not matter if B isan abstract base or not. The same issues apply. So ALWAYS use avirtual destructor unless you have a very very good reason.What is a good reason? Well, you have a class like: struct TinyPoint { char x,y; };This class takes up two bytes. A virtual destructor will probably add4 bytes to this for the vtbl pointer. If you are going to allocate amillion of them, then you will have 2meg taken up by data, and 4megtaken up by pointers, that all point to the same thing. Thus, this isprobably a good case for not declaring a virtual destructor.
#include <iostream> using namespace std; 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; }
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.
We can declare pure virtual destructor but need to specify its body. Class Base { ~Base() = 0; }
Base::~Base(){}
Pure virtual destructor does the same thing which other virtual functions do, makes Base class abstract. I didn't find any other reason to make virtual destructor pure.... does any body knows???