这个程序是否定义明确,如果没有,为什么?
#include <iostream>
#include <new>
struct X {
int cnt;
X (int i) : cnt(i) {}
~X() {
std::cout << "destructor called, cnt=" << cnt << std::endl;
if ( cnt-- > 0 )
this->X::~X(); // explicit recursive call to dtor
}
};
int main()
{
char* buf = new char[sizeof(X)];
X* p = new(buf) X(7);
p->X::~X(); // explicit call to dtor
delete[] buf;
}
我的推理:虽然两次调用析构函数是未定义的行为,但根据 12.4/14,它的确切含义是:
如果为生命周期已结束的对象调用析构函数,则行为未定义
这似乎并没有禁止递归调用。当对象的析构函数正在执行时,对象的生命周期还没有结束,因此再次调用析构函数不是 UB。另一方面,12.4/6 说:
在执行主体后 [...] 类 X 的析构函数调用 X 的直接成员的析构函数,X 的直接基类的析构函数 [...]
这意味着在从析构函数的递归调用返回后,所有成员和基类析构函数都将被调用,并且在返回上一层递归时再次调用它们将是 UB。因此,没有基类且只有 POD 成员的类可以在没有 UB 的情况下具有递归析构函数。我对吗?