c++ - 直接调用析构函数后 `new (this) MyClass();`是不是未定义行为?

标签 c++ this undefined-behavior placement-new

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.

该方面具体来说是未定义的行为。

关于c++ - 直接调用析构函数后 `new (this) MyClass();`是不是未定义行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6224121/

相关文章:

c++ - 浮点类型作为 C++20 中的模板参数

c++ - 返回你自己内部拷贝的正确方法是什么?

javascript - this 关键字和数组

c++ - 分配过大的堆栈结构是未定义的行为吗?

c - 通过一些错误示例了解 memcpy() 的行为

c++ - 防止 sleep 模式

python - 如何防止图形项目被绘制出来?以及如何为QGraphicsView和QGraphicsScene具有不同的背景色

javascript - 为什么返回函数时要修复 'this'?

jquery - 如何查看是否点击同一个元素两次? jQuery

c - 为什么这些构造使用增量前和增量后未定义的行为?