删除前手动调用析构函数

时间:2017-04-03 17:35:38

标签: c++ destructor undefined-behavior delete-operator

auto obj = new Object;
obj->~Object();
delete obj;

我知道这很不寻常,但它是否定义了行为?它会引起任何令人惊讶的问题吗?

3 个答案:

答案 0 :(得分:8)

您只能如果obj指向的销毁对象替换为新对象:

auto obj = new Object;
obj->~Object();

new (obj) Object();
delete obj;

否则,您将调用未定义的行为。

你应该明白:

  • new调用operator new获取内存,然后调用提供的construtor来创建对象
  • delete调用对象的析构函数,然后调用operator delete来“返回”内存。
编辑:正如Bo Persson指出的那样,如果你不能提供例外保证,这不是一个好主意

答案 1 :(得分:1)

导致对象析构函数被调用两次是Undefined Behavior。您没有遵守规则,允许编译器对您的代码执行任何操作。只是不要那样做

答案 2 :(得分:0)

如果我们严格遵循标准语言,那么您的代码就会导致未定义的行为并导致问题。

但是,如果任何平台遇到以下问题,我会非常惊讶:

struct Foo {};

void testFoo()
{
   Foo* foo = new Foo();
   foo->~Foo();
   foo->~Foo();
   foo->~Foo();
   foo->~Foo();
   foo->~Foo();
   foo->~Foo();
   foo->~Foo();
   delete foo;
}

另一方面,如果任何平台可以执行以下操作而不会遇到问题,我会非常惊讶。

struct Bar {std::string s;};

void testBar()
{
   Bar* bar = new Bar{"test"};
   bar->~Bar();
   delete bar;
}