C++ allows virtual functions to resolve function calls at run-time. This is called late-binding. Like virtual functions, C++ allows virtual destructors to delete the objects properly in an inheritance hierarchy.
C++ allows calling virtual functions from class destructors. But what will happen when it calls these virtual functions from class destructors? Let’s take an example, to understand this;
// Sample.cpp // #include <iostream> using namespace std; class Shape { public: virtual void Display() { cout << "Shape" << endl; } }; class Circle : public Shape { public: void Display() { cout << "Circle" << endl; } }; // main() function // int main() { Shape *pShape = new Circle(); if ( pShape != NULL ) { pShape->Display(); delete pShape; } return 0; }
Compile and run this sample program. Observe the result that; it is displaying a “Circle” message.
cl /EHsc Sample.cpp
In the code, we are calling the Display function through Shape‘s object. We expect that it will call Shape‘s Display function. Actually, it will call Circle‘s Display function. Because the “pShape” variable actually holds the address of Circle‘s object. So, it will call Circle‘s Display function. This is the correct behavior.
We will call the virtual function from the class’s destructor and observe the result. Let’s modify our program like the below:
// Sample.cpp // #include <iostream> using namespace std; class Shape { public: virtual ~Shape() { Display(); } virtual void Display() { cout << "Shape" << endl; } }; class Circle : public Shape { public: void Display() { cout << "Circle" << endl; } }; // main() function // int main() { Shape *pShape = new Circle(); delete pShape; return 0; }
From the above program, we expect that; it will display a “Circle” message on the console; based on our discussion from our previous example code. In this program, we have slightly changed our code in such a way that instead of calling the Display function from main()
, we are calling it from the class’s destructor. So, as per the virtual function concept, C++ should resolve exact function calling at run-time.
But in this scenario, C++ calls the local Display function instead of resolving the proper Display function at run-time. C++ ignores virtual functions if we call them from the class’s destructors.
The reason is, in the inheritance hierarchy, the derived class’s destructor will call first, before calling its base class’s destructor. From our example code, Circle‘s class object will be destroyed, before destroying Shape‘s class object. If we call a virtual function from the base class’s destructor; how C++ calls the derived class’s virtual function; if the derived class object is already destroyed? That is the reason, C++ ignores virtual functions from class destructors.
Because of this, from the above code, it will display a “Shape” message.
..