以下程序:
#include <iostream>
using namespace std;
class Test
{
public:
Test() { cout << "Constructor is executed\n"; }
~Test() { cout << "Destructor is executed\n"; }
};
int main()
{
Test(); // Explicit call to constructor
Test t; // local object
t.~Test(); // Explicit call to destructor
return 0;
}
Run Code Online (Sandbox Code Playgroud)
打印以下输出:
Constructor is executed
Destructor is executed
Constructor is executed
Destructor is executed
Destructor is executed
Run Code Online (Sandbox Code Playgroud)
我的问题是即使在 main() 中显式调用析构函数之后,为什么编译器在退出 main() 之前隐式调用析构函数?
作为一个附带问题,除了在删除运算符中使用之外,是否还有其他使用显式调用析构函数的策略?
您引入了未定义的行为。
按照标准:
§ 12.4 析构函数
(11) 隐式调用析构函数
(11.3) —当创建对象的块退出时,具有自动存储持续时间 (3.7.3) 的构造对象(6.7),
和
15 一旦为一个对象调用了析构函数,该对象就不再存在;如果为生命周期已结束 (3.8) 的对象调用析构函数,则行为未定义。[ 示例:如果显式调用自动对象的析构函数,并且随后以通常会调用对象的隐式销毁的方式保留块,则行为未定义。—结束示例]
您显式调用析构函数或通过调用t.~Test(),然后在对象离开作用域时隐式调用它。这是未定义的。
该标准还提供了此注释:
14 [ 注意:很少需要显式调用析构函数。此类调用的一种用途是用于使用放置新表达式放置在特定地址的对象。这种显式放置和销毁对象的使用对于处理专用硬件资源和编写内存管理设施可能是必要的。