c – 直接调用析构函数后是`new(this)MyClass();`未定义的行为?
作者:互联网
在this question of mine,@ DeadMG说通过this指针重新初始化类是未定义的行为.标准中有没有提到它?
例:
#include <iostream>
class X{
int _i;
public:
X() : _i(0) { std::cout << "X()\n"; }
X(int i) : _i(i) { std::cout << "X(int)\n"; }
~X(){ std::cout << "~X()\n"; }
void foo(){
this->~X();
new (this) X(5);
}
void print_i(){
std::cout << _i << "\n";
}
};
int main(){
X x;
x.foo();
// mock random stack noise
int noise[20];
x.print_i();
}
Example output at Ideone(我知道UB也可能是“看似正确的行为”).
请注意,我没有在类之外调用析构函数,因为没有访问生命周期结束的对象.另请注意,@ DeadMG表示直接调用析构函数是可以的 – 因为它为每个构造函数调用一次.
解决方法:
如果它与堆栈展开没有冲突,那就没关系.
您销毁对象,然后通过指针重建它.如果您需要构造和销毁没有默认构造函数的对象数组,那么这就是您要做的.
问题是这是不安全的例外.如果调用构造函数抛出异常并且堆栈被解开并且第二次调用析构函数会怎么样?
{
X x;
x.foo(); // here ~X succeeds, then construction fails
} //then the destructor is invoked for the second time.
那个方面特别是未定义的行为.
标签:placement-new,c,undefined-behavior,this 来源: https://codeday.me/bug/20190929/1832489.html