c++析构函数在同一对象上被调用2次

c++ destructor getting called 2 times on the same object?

本文关键字:调用 2次 对象 析构函数 c++      更新时间:2023-10-16

我有以下代码片段:

#include<iostream>
using namespace std;
class Test {
public:
    Test()  { cout << "Constructor is executedn"; }
    ~Test() { cout << "Destructor is executedn";}
    void show()  {  this->Test::~Test(); }
};
int main() {
    Test t;
    t.show();
    return 0;
}

这是输出:

Constructor is executed
Destructor is executed
Destructor is executed

问题:如果t.show()已经调用了"this"对象(即当前对象)上的析构函数,导致"destructor is execute"显示一次,那么是什么导致它第二次显示?在这种情况下,哪个物体会被摧毁?

当自动变量超出范围时,它们会被销毁。CCD_ 2是当CCD_ 3结束时超出范围的自动变量。这是第二次调用析构函数。第一次是通过Test::show,因为函数手动销毁了this指向的对象。

由于C++遵循的哲学是不为不使用的东西付费,因此在对超出范围的自动变量调用析构函数之前,没有任何类型的运行时检查。当然,实际发生在第二个析构函数调用上的是UB。小心鼻腔恶魔。

Pradhan给了你一个易于理解的解释,我将分享处理对具有自动存储持续时间的对象的显式析构函数调用的特定规则,见标准的3.8p8节:

如果程序以静态、线程或自动存储持续时间结束T类型对象的生存期,并且T具有非平凡的析构函数,则程序必须确保在隐式析构函数调用发生时,原始类型的对象占据相同的存储位置;否则程序的行为是未定义的。即使块退出时出现异常,情况也是如此。

你违反了这个规则,所以你得到了未定义的行为。

6.7p2中描述了"隐式析构函数调用":

每次执行声明语句时,都会初始化具有自动存储持续时间的变量。块中声明的具有自动存储持续时间的变量在从块