C++ - Destructors

C++ - Destructors

Destructors
----------------------------------------------------------------------------
Posting a short note on Destructors.


A normal destructor is a special function,
which is called when a object is destroyed.


There are two ways in which an object can be created:
1. <class name> <object name>
2. <class name>* <object ptr name> = new <class name>


The cleanup for the first type is automatically handled by c++,
by the scope rules for that object. 
ex: if the object is created local to the fucntion, then when the
function finishes execution, the destructor for the class is automagically invoked.


The cleanup for the second type of object creation,
has to be done explicitly via a delete call for the object.


Stuff's pretty clean till now. 
It gets little tricky when we have, inheritance into the picture.


Suppose we are having a derived class, which inherits a base class.
If we create an object of the derived class, and delete it, as in below code.
----------------------------------------------------------------------------
class Base
{
    public:
    ~Base() 
    {
        cout << "Base Destructor\n"; 
    }
};


class Derived:public Base
{
    public:
    ~Derived() 
    { 
        cout<< "Derived Destructor"; 
    }
}; 


int constructor_destructor_demo()
{
    Derived* d = new Derived;
	delete d;
}
----------------------------------------------------------------------------
Now since the object pointer is of derived class.
Everything works like clockwork.
since At first the Derived class destructor is called and then Base calss destrutor is called,
as it is inherited.




The real issue comes when we are doing an upcast or using polymorphism.
An UPCAST is done to leverage the power of "programming to an interface".
----------------------------------------------------------------------------
class Base
{
    public:
    ~Base() 
    {
        cout << "Base Destructor\n"; 
    }
};


class Derived:public Base
{
    public:
    ~Derived() 
    { 
        cout<< "Derived Destructor"; 
    }
}; 


int constructor_destructor_demo()
{
    Base* d = new Derived;
	delete d;
}
-----------------------------------------------------------------------------
In this case we see, that only the Base class destructor is called.
And the Derived class Destructor is not called at all.


Why Derived Destructor is not called?? This looks strange.
This is because the base class pointer does not have any knowledge of the derived class object. So if we are able to provide this information to the base class, then it will be able to call the Derived class destructor.


This is achieved by using virtual keyword for the base class destructor.
Let see what will happen if we use the virtual keyword in the below diagram.



|                                |          
|--------------------------------| <------ Derived Class memory layout
|  Base::_type                   |          
|--------------------------------|          
|  Base::_vptr_Base              | ------->|-------------------------|
|                                |         |   type_info Derived     |
|--------------------------------|         |-------------------------|
                                           |   Derived::~Derived     |
                                           |-------------------------|


As we see in the above diagram, the vtable pointed to by the vptr of the base class, now has the reference to Derived Class Destructor.


So the statement delete <Base class pointer>,
will be converted to (*Base->vptr[1])(Base), this is equivalent
to calling delete <Derived Class Object>.
























        



To view or add a comment, sign in

More articles by Venkatesh TK

Others also viewed

Explore content categories