对于普通对象(即使是const
对象),通过显式调用析构函数来结束它们的生命周期是允许的。之后,程序可以使用放置new
在相同的内存位置开始另一个对象生命周期。
但是调用constexpr
对象的析构函数是否合法?它是否会导致一些有用或至少良好构造的程序?
很容易想象相反的情况:
struct A{
int v = 0;
constexpr void foo() { v ? throw 1 : ++v; }
constexpr ~A() { foo(); }
};
constexpr A y;
int main() { y.~A(); y.~A(); }
这个(很可能格式不正确的)程序在任何编译器中被接受而没有任何警告:https://gcc.godbolt.org/z/aqMbfjxKT。在Clang中,它通过
A
类的constexpr
析构函数抛出了异常。
new
在相同的内存位置启动另一个对象生命周期。但是,new(&y) A;
不会有效,因为&y
是const A*
,而没有将新的A
放置在内存中后,在对象生命周期结束后会调用其析构函数。您需要强制转换掉const
才能使用放置new,但这样会产生未定义行为。 - Ted Lyngmo