C++ destructor overloading

I know that for a base class with virtual functions, it is generally necessary to define the destructor of the base class as a virtual function, so as to achieve a reasonable release of resources, and I also know that when a derived class is overloaded, it only needs to clean up its own objects, However, sometimes there are still some doubts, so I wrote a simple example to clear the doubts. The following is the example content:

#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>

intmain ()
{
    _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 the bachelorHolder is deleted, that is:

class bachelorHolder : public studentHolder
{
public:
    bachelorHolder()
        : studentHolder()
    {

    }

private:
    bachelor bcl;
};

In this case, the object is still well cleaned up because C++ creates a destructor for the class by default, and if the base class is virtual, the derived class creates a virtual function that overrides the base class. The result is still:

If in the above case, remove the virtual of the studentHolder destructor, that is:

class studentHolder
{
public:
    studentHolder()
    {

    }

    ~studentHolder() {}


private:
    student st;
};

The result will become:

However, note that here, it is just that the destructor of the derived class is not called, and the resource (allocated heap memory) will still be released well. Here, you can see if we comment out the delete holder; in the main function:

intmain ()
{
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    studentHolder* holder = new bachelorHolder();
    // delete holder;
    return 0;
}

In debug mode, when debugging, you will get the following results in the output window:

And even if the main function is changed to the following:

intmain ()
{
    _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 will be no memory leak display. The general content is the above display, you can refer to it when you have doubts.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325201267&siteId=291194637