我有以下代码段:
#include<iostream>
using namespace std;
class Test {
public:
Test() { cout << "Constructor is executed\n"; }
~Test() { cout << "Destructor is executed\n";}
void show() { this->Test::~Test(); }
};
int main() {
Test t;
t.show();
return 0;
}
这是输出:
Constructor is executed
Destructor is executed
Destructor is executed
问题:如果t.show()
已经在&#34上调用了析构函数,那么&#34;对象(即当前对象),导致&#34;析构函数被执行&#34;要显示一次,然后是什么原因导致它第二次显示?在这种情况下哪个对象被破坏了?
答案 0 :(得分:8)
自动变量超出范围时会被破坏。 Test t
是一个自动变量,在main
结束时超出范围。这是第二次调用析构函数。第一次是Test::show
,因为该函数会手动销毁this
指向的对象。
因为,C ++遵循的理念是不支付你不能使用的东西,所以在调用超出范围的自动变量的析构函数之前,没有任何类型的运行时检查。当然,在第二个析构函数调用中发生的实际是UB。小心nasal demons。
答案 1 :(得分:3)
Pradhan为您提供了一个易于理解的解释,我将分享处理具有自动存储持续时间的对象的显式析构函数调用的特定规则,可在标准的3.8p8节中找到:
如果程序以静态,线程或自动存储持续时间结束
T
类型的对象的生命周期,并且如果T
具有非平凡的析构函数,则程序必须确保当隐式析构函数调用发生时,原始类型占用相同的存储位置;否则程序的行为是不确定的。即使该块以异常退出,也是如此。
您违反了此规则,因此您会得到未定义的行为。
“隐式析构函数调用”在6.7p2中描述:
每次执行声明语句时,都会初始化具有自动存储持续时间的变量。块中声明的具有自动存储持续时间的变量在退出时被销毁 块。