Wednesday, May 8, 2013

Virtual destructors for base class


Always forget to do this....mark!

Virtual destructors are useful when you can delete an instance of a derived class through a pointer to base class:
class Base 
{
    // some virtual methods
};

class Derived : public Base
{
    ~Derived()
    {
        // Do some important cleanup
    }
}
Here, you'll notice that I didn't declare Base's destructor to be virtual. Now, let's have a look at the following snippet:
Base *b = new Derived();
// use b
delete b; // Here's the problem!
Since Base's destructor is not virtual and b is a Base* pointing to a Derived object, delete bhas undefined behaviour. In most implementations, the call to the destructor will be resolved like any non-virtual code, meaning that the destructor of the base class will be called but not the one of the derived class, resulting in resources leak.
To sum up, always make base classes' destructors virtual when they're meant to be manipulated polymorphically.
If you want to prevent the deletion of an instance through a base class pointer, you can make the base class destuctor protected and nonvirtual; by doing so, the compiler won't let you call delete on a base class pointer.
You can learn more about virtuality and virtual base class destructor in this article from Herb Sutter.

A virtual constructor is not possible but virtual destructor is possible. Let us experiment....
#include <iostream>
using namespace std;
class base
{

public:
    base(){cout<<"Base Constructor Called\n";}
    ~base(){cout<<"Base Destructor called\n";}

};
class derived1:public base
{

public:
    derived1(){cout<<"Derived constructor called\n";}
    ~derived1(){cout<<"Derived destructor called\n";}

};
int main()
{

    base* b;
    b=new derived1;
    delete b;

}
The above code output the following....
Base Constructor Called
Derived constructor called
Base Destructor called
The construction of derived object follow the construction rule but when we delete the "b" pointer(base pointer) we have found that only the base destructor is call.But this must not be happened. To do the appropriate thing we have to make the base destructor virtual. Now let see what happen in the following ...
#include <iostream>
using namespace std;
class base
{

public:
    base(){cout<<"Base Constructor Called\n";}
    virtual ~base(){cout<<"Base Destructor called\n";}

};
class derived1:public base
{

public:
    derived1(){cout<<"Derived constructor called\n";}
    ~derived1(){cout<<"Derived destructor called\n";}

};
int main()
{

    base* b;
    b=new derived1;
    delete b;

}
the output changed as following
Base Constructor Called
Derived constructor called
Derived destructor called
Base Destructor called
So the destruction of base pointer(which take an allocation on derived object!) follow the destruction rule i.e first the derived then the base. On the other hand for constructor there are nothing like virtual constructor. Thanks (Write Code and have fun!!!)

No comments:

Post a Comment