I know that for the base class with virtual function, the destructor of the base class needs to be defined as virtual function to realize the reasonable release of resources, and I also know that when the derived class is overloaded, it only needs to clean up its own objects, but sometimes it still has some doubts, so I wrote a simple example to eliminate doubts. Here is the example:
#include <iostream> class student { public: student() {} ~student() { std::cout << "a student" << std::endl; } }; class bachelor { public: bachelor() {} ~bachelor() { std::cout << "a bachelor" << std::endl; } }; class studentHolder { public: studentHolder() { } virtual ~studentHolder() {} private: student st; }; class bachelorHolder : public studentHolder { public: bachelorHolder() : studentHolder() { } ~bachelorHolder() override { } private: bachelor bcl; };
Here is the code where the call is made:
#define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); studentHolder* holder = new bachelorHolder(); delete holder; return 0; }
In this case, the correct cleanup is performed:
In this case, if the destructor in bachelorHolder is deleted, that is:
class bachelorHolder : public studentHolder { public: bachelorHolder() : studentHolder() { } private: bachelor bcl; };
In this case, the object is still cleaned well, because C + + will create a destructor for the class by default, and if the base class is a virtual function, the derived class creates a virtual function that overrides the base class. The result remains:
If in the above case, virtual is removed from the studentHolder destructor, that is:
class studentHolder { public: studentHolder() { } ~studentHolder() {} private: student st; };
The result will be:
Note, however, that the destructor of the derived class is not called, and the resources (allocated heap memory) will be released well. Here, you can see that if we comment out the delete holder; in the main function:
int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); studentHolder* holder = new bachelorHolder(); // delete holder; return 0; }
When debugging in debug mode, you will get the following results in the output window:
Even if the main function is changed as follows:
int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); studentHolder* holder = new bachelorHolder(); delete reinterpret_cast<void*>(holder); return 0; }
In the output window, there is no display of memory leaks. The general content is the above display. When you have doubts, you can refer to it.