C++ language has the feature called inheritance. Base class can be derived to another class and further in the inheritance level. Multiple levels of inheritance is possible. An object of type derived class has to be created and destructed in proper way. Let us understand the creation and destruction of any c++ object.
Constructor call sequence
C++ compiler ensures the constructor will be called in the order how they are getting created. Base class will be created and then derived class. So the sequence in which constructors are called is in the same order in the inheritance hierarchy. Base construction will be called and then the derived ones. Compiler maintains compile time static table for constructors and they often known as ctor table.
Destructor call sequence
Now comes the destruction part. Destruction cannot happen in the order like construction happened. Base has to be there till the end before derived is destructed. So destruction happens in the opposite sequence than construction. First derived class will be destroyed and then base class. Compiler maintains compile time static table for destructor and they often known as dtor table. Sequence of destructor events are called can be illustrated in the below flow diagram.
Now let us understand with a program. Here we want to see how the sequence will be.
base construction derived construction mem allocated for name derived destruction mem de-allocated for name base destruction
Destructor call sequence with base pointer
Now let us see what would happens when the derived object is deleted with base type pointer
base construction derived construction mem allocated for name base destruction
Here derived destruction event is missing and derived destructor is not getting called by compiler. This is common problem when classes are designed with early binding or compile time binding. As the type of the object is base and as per the static dtor table compiler only calls base destructor. This also leads to memory leak as string member name is not getting de-allocated.
To ensure proper destructor call sequence, we must make the base destructor as virtual. This ensures dynamic/runtime binding of the destructor through vtable mechanism. Compiler do not use dtor table when destructor is virtual. Like normal virtual function it will loop up the address vptr -> vtable entry and call indirectly.
C++ compiler will create a vtable and put the first entry as destructor function. vptr of base will point to vtable of base class. So in the early stage base will be created and the vtable entry 0 will point to the destructor of base ~base().
Now derived will be created and compiler will overwrite the vptr with the address of the vtable of derived. derived vtable entry 0 will point this to function ~derived().
Vtable assignment in construction chain
Destructor chain and call sequence
Now a delete on base pointer is called. Since this base destructor is virtual one, compiler will never call ~base() by dtor table. Instead this will lookup vptr and then vtable function 0. Then this will be called using function pointer. As per last constructed override, vptr points to vtable of derived class and vtable function 0 location points to derived destructor i.e. ~derived(). Eventually derived destructor will be called. Now after exit of ~derived() compiler will assign vptr to vtable of base class.
At this point object is having vptr pointing to vtble of base. Compiler will again lookup address of destructor and call ~base(). After the exit of ~base() vptr will be assigned to NULL. No more virtual call is possible and object is at highest level in the inheritance hierarchy so the delete call will ended.
Here we have illustrated two levels of inheritance. However this inheritance level can be any level and this mechanism will work fine. After modifying the prototype ~base() to virtual ~base() the sequence will be as expected as below.Proper Output:
Output after this change: base construction derived construction mem allocated for name derived destruction mem de-allocated for name base destruction
About our authors: Team EQA
You have viewed 1 page out of 62. Your C++ learning is 0.00% complete. Login to check your learning progress.
Learn on Youtube