The cPP subclass destructor was not called

Why when the destructor of the parent class is defined as virtual, delete pTest2 releases the resources of Derived, otherwise it can only release the resources of Base, and delete pTest1 can release the resources of Derived and Base

class Base
{
public:
    ~Base() {
        cout << "Base destructor!" << endl;
    };
};

class Derived: public Base
{
public:
    ~Derived() {
        cout << "Derived destructor!" << endl;
    };
};

int main() {

    Derived *pTest1 = new Derived();
    Base *pTest2 = new Derived();

    delete pTest1;
    delete pTest2;
    return 0;
}
Mar.21,2022

it can only be said that cpp is designed in this way. You can say that it is not well designed.

there is a question on sf: when not to use virtual destructor?

for reference
https://stackoverflow.com/que.

The

virtual function means that each allocated object increases memory overhead through the virtual function table pointer.

therefore, if your program involves allocating a large number of objects, it is worth avoiding all virtual functions in order to save an additional 32 bits per object.

in all other cases, you will save your debugging pain and virtualize the destructor.


the following is only a personal understanding, if there are any errors, please point out, thank you.

first of all, two concepts need to be clarified:

the first is the meaning of virtual.
when we call a method of a class object through a pointer, the compiler only has two information: the pointer type and the address. It can only infer what the object instance actually looks like in memory according to the pointer type.
when we call a non-virtual method, CPP can only judge the method that should be called according to the pointer type, if the pointer is a base class pointer. Even if it points to a subclass object, the compiler doesn't know it, so it only calls the corresponding method in the base class.
only if virtual,CPP is declared will a virtual table, be created in the object instance that contains the addresses of all the virtual functions actually held by the class object. In this case, we use a base class pointer to point to the subclass object and call the virtual method. CPP will call the function pointer at the corresponding location in the virtual function table, and the subclass method can be called correctly.

the second is how destructors work.
when we call a class destructor, from this class up, each base class destructor is called one by one.
this is why delete subclass pointers, subclass and parent class destructors are called correctly.

obviously, when a derived class object is deleted through a base class pointer,
if the destructor of the base class is non-virtual, CPP will directly call the destructor of base class. The destructor of, derived class cannot be executed naturally.
when the destructor of the base class is virtual, CPP finds the function pointer of the destructor held by the object instance in vtbl and calls it. Then, according to the basic operation of the destructor, the subclass is called first, and then the base class.


 
The semantics of 

delete is to call the destructor
if the destructor is modified by virtual, CPP ensures that the delete call subclass is destructed and inserted before the destructor.

itself a delete and a pointer only invokes its own destruction.

Menu