This question is asked in many interviews that why we need 'Virtual Destructor'. In what scenarios, it is needed? And What is the advantage/disadvantage of using it? Also if virtual destructor is there why there is nothing like 'Virtual Constructor' in C++ ?
For understanding this, we first need to have a brief idea about virtual keyword. And subsequently we need to revisit the concept of polymorphism.
What is polymorphism and what are it's advantage?
Polymorphism is simply defined as 'Single Interface Multiple Implementations'. It means that we do not need to have different interfaces (or names) for same type of functionality in same type of objects. There are two type of polymorphism:
1) Static Polymorphism:
Function overloading allows programs to declare multiple functions having the same name (but with different arguments).I don't want to go in that details and assuming that you know that.
2) Dynamic Polymorphism:
Lets have an example. Dog and Lion are of same type (Animal) but speaks differently. Lion roars while Dog barks. If we don't know before hand whether we are dealing with a Dog or with a Lion, we can't predict the actual behavior.
Code:
class Animal
{
public:
Animal(){};
~Animal(){};
void speak()
{
printf("Animal Sound\n");
};
};
class Dog: public Animal
{
public:
Dog(){};
~Dog(){};
void speak()
{
printf("Dog Barks\n");
};
};
class Lion: public Animal
{
public:
Lion(){};
~Lion(){};
void speak()
{
printf("Lion Roars\n");
};
};
main()
{
Dog d;
Lion l;
Animal *p;
p = &d;
p->speak; //prints "Animal Sound"
p = &l;
p->speak; //prints "Animal Sound"
}
class Animal
{
public:
Animal(){};
~Animal(){};
virtual void speak()
{
printf("Animal Sound\n");
};
};
This 'virtual' keyword does wonder here; doesn't it? It ensures that correct method is called. How does it do it? It maintains a 'vtable' for every class (in which virtual function is defined) and from there it comes to know that which implementation should be called. Another important thing about virtual function is that it maintains its virtual behavior in all subsequent inherited classes.
Another concern was that what is the cost we pay for having this behavior:
- The class size increases by the size of an address. This address is actually the address of vtable. No matter how many virtual function are there, it just carry one vtable address.
- Every time a function is called, we need to refer vtable for finding exact definition.
Virtual Destructor:
I hope that by now, the need of virtual destructor is clear to most readers. For those who are still confused, virtual destructor are there to ensure that correct destructor is called. Another fact to notice is that virtual destructor (and virtual functions) comes is picture only when we construct an object polymorphically. If we are sure that we won't call a function polymorphically, we need not to have virtual functions.
Example:
class Base
{
.......
.......
};
class Derived : public Base
{
.......
.......
}
main()
{
Derived d;
} // No advantage of virtual destructor
main()
{
Base *b = new Derived();
delete b; // Virtual destructor ensure right call
}
Virtual Constructor:
Now, the question arises that why we don't need a virtual constructor like virtual destructor. The answer is simple, at the time object creation ( new Derived() ) we don't know if we are assigning this address to some base class pointer and we simply call right constructor. So no need to have any virtual constructor.
But at the time when scope ends (delete b), we don't know if we are deleting a base class object or derived class object. We know this through vtable and thus virtual destructor comes in picture. If we don't have a virtual destructor then while deletion, base destructor will be called wrongly.
Subscribe - To get an automatic feed of all future posts subscribe here, or to receive them via email go here and enter your email address in the box. You can also like us on facebook and follow me on Twitter @akashag1001.
Thanks Akash. This was very helpful.
Very well explained, thanks!