当我使用dynamic_cast并删除对象删除时,析构函数是如何工作的?

When I use dynamic_cast and delete the object delete , how the destructor works?

本文关键字:删除 何工作 工作 析构函数 dynamic cast 对象      更新时间:2023-10-16

我为它创建一个派生类的对象和一个基类点, 然后我使用dynamic_cast将基类点转换为派生类点。 我删除了派生类点,但程序调用派生析构函数和基析构函数。为什么程序调用基析构函数?毕竟,基本析构函数不是一个虚函数。

#include<iostream>
#include<stdlib.h>
using namespace std;

class con {
private:
double num;
public:
con() {
num = 0;
cout << "default..." << endl;
}
void getnum() {
cout << num << endl;
}
};


class base {
public:
virtual void A() {
cout << "it is base A" << endl;
}
void B() {
cout << "it is base B" << endl;
}
~base() {
cout << "it is base decon" << endl;
}
};

class child : public base {
public:
void A() {
cout << "it is child A" << endl;
}
void B() {
cout << "it is child B" << endl;
}
~child() {
cout << "it is child decon" << endl;
}
};

int main(int argc, char** argv) {
base* b = new child();
child* c = dynamic_cast<child*>(b);
delete c; //the program print "it is child decon"   "it is base decon"
getchar();
return 0;
}

情况 1:如果删除指针派生类,它始终首先调用派生类的析构函数,然后调用基类的析构函数。

情况 2:如果使用非虚拟基类析构函数删除指向派生类的基类的指针,则它不知道派生类,因此它只会删除基类。

情况 3:如果使用虚拟基类析构函数删除指向派生类的基类的指针,它将使用虚拟调度到派生类的析构函数,然后调用基类的析构函数。

案例 2 很糟糕。 它可能导致资源泄漏等。 应通过在旨在作为基类的类中始终声明析构函数虚拟来避免这种情况。

您的示例说明了案例 1。

如果您想查看案例 2 的实际效果,请尝试delete b而不是示例中的delete c

C++中的析构函数不会"重载";它们会链接起来。当你说

{
child c;
}

然后在右大括号处,编译器将插入对~child()的调用,而 又会调用~base()(以及其他基类的析构函数,如果有的话(。这对于避免内存泄漏至关重要——否则base的成员将如何被摧毁?请注意,这不需要virtualbase析构函数。

当您使用delete手动销毁某些内容时,这的工作方式相同:

child* c = new child{};
delete c; // runs ~child(), which calls ~base()

同样,这不需要virtual析构函数。

虚拟析构函数所做的是允许您使用指向base的指针销毁动态类型child变量,即

child* c = new child{}
base* b = c;
delete b; // Will call ~child() if destructor is virtual, otherwise ~base()