Why we use Virtual Destructor?

Questions by varshakumbhar   answers by varshakumbhar

Showing Answers 1 - 25 of 25 Answers

Nitin Gupta

  • Jan 3rd, 2006
 

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.

  Was this answer useful?  Yes

samiksc

  • Jan 19th, 2006
 

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.

  Was this answer useful?  Yes

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.

narendra kumar

  • May 5th, 2006
 

thanx nitin gupta

is there any real time example towords this virtual destructor. please send me.

really i got the whole concept of virtual destructor.

  Was this answer useful?  Yes

Suganthi

  • Jul 11th, 2006
 

A very good explaination.

Thx.

  Was this answer useful?  Yes

Suganthi

  • Jul 11th, 2006
 

excellent

  Was this answer useful?  Yes

muralidhar

  • Jan 9th, 2007
 

Hello all.
This is the simple example code..
#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;
}

  Was this answer useful?  Yes

Faheem Arshad

  • Mar 15th, 2007
 

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.

vineet

  • Jul 4th, 2007
 

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???

regards
Vineet

  Was this answer useful?  Yes

Amicable

  • Nov 5th, 2008
 

When I tried to use pure virtual destructor as,

class Base {

Base {cout <<"constructor";};
virtual ~Base() = 0;
};

Base :: ~Base();

It is giving me an error as- "Multiple declaration of ~Base()"

Why does it give this error?? Is pure virtual destructor not allowed ??

  Was this answer useful?  Yes

As far as i understand the key word "virtual" is that when ever we try to use pointers i.e.
-> calling a funtion of derived class thru the pointer of base class pointing to the object of that derived class:

Base *p=new Derived();
p->vfunc();

-> deleting an object of derived class thru the pointer of base class pointing to that object:

Base *p=new Derived();
delete p;

virtual need to be used so as to call the correct function.Else if we don't use pointers then there no need of keyword virtual.

  Was this answer useful?  Yes

VENKATGOPU

  • Jun 10th, 2009
 

/*without virtaul*/
#include <iostream>
#include<conio.h>
using namespace std;
class Base
{
       public:
          void fun()
          {
            cout<<"Base class function"<<endl;    
          }
};
class Derived: public Base
{
          void fun()
          {
            cout<<"Derived class function"<<endl;    
          }
};
int main()
{
        Base *ptr;     //Base class pointer
        Derived obj;   //Derived class object
        ptr=&obj;      //Base class pointer points
                            //to derived class object  

        ptr->fun();    /*Base class function called even Base
                      /pointer points to Derived object. Bcz
                      /this is compile time polymorphism means
                      /the function will be called and linked
                       /during compile time based on the
                       /arguement or type of variable (or pointer or
                       /return type of funtion). In short this is
                       /also known as function overloading  */
        getch();
        return 0;
}

Note: Here type of pointer is Base class. Hence in compile time the base class function (only available) will be called

Output

Base class function

                /*with virtaul*/

#include <iostream>
#include<conio.h>
using namespace std;
class Base
{
       public:
          virtual void fun()
          {
            cout<<"Base class function"<<endl;    
          }
};
class Derived: public Base
{
          void fun()
          {
            cout<<"Derived class function"<<endl;    
          }
};
int main()
{
        Base *ptr;     //Base class pointer
        Derived obj;   //Derived class object
        ptr=&obj;      //Base class pointer points

                       //to derived class object  

       ptr->fun();    /*Derived class function will be called. Bcz
                       /this is run time polymorphism means
                       /the function will be called during 
                       /run time and linked during run time.
                       /(this is achieved by using "virtual")  
                       /In short this is also
                       /known as virtual function */
        getch();
        return 0;
}

Note: Here "virtual" keyword used in base class function. this keyword allow the compiler to call and link the appropriate function in run time.

Output

Derived class function

/*virtual destructor*/

#include <iostream>
#include<conio.h>
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;}
};
int main()
{
        Base *Var = new Derived(); /* constructor isn't like
                                   /normal function i.e. the
                                   /constructor only linked at
                                   /compile time.*/
        delete Var;              /* But the destructor
                                 /will be called at compile time
                                 /when we will not use "virtual".
                                 /The destructor will be called at
                                 /run time when we use "virtual"  */
        getch();
        return 0;
}

Note: Here we are using "virtual". so Derived class Destructor will be called first

Output
Constructor: Base         //constructor is linking at compile time
Constructor: Derived        
Destructor : Derived     // run time linking bcz we use virtual 
Destructor : Base

Thanks & Regards
 Venkat Gopu

  Was this answer useful?  Yes

Give your answer:

If you think the above answer is not correct, Please select a reason and add your answer below.

 

Related Answered Questions

 

Related Open Questions