为什么在析构函数可以不显式调用构造函数?

Dan*_*ica 28 c++ constructor destructor placement-new explicit-destructor-call

在下面的C++代码中,我可以显式调用析构函数而不是构造函数.这是为什么?不明确的ctor调用与dtor案件更具表现力统一性吗?

class X { };

int main() {
  X* x = (X*)::operator new(sizeof(X));
  new (x) X;  // option #1: OK
  x->X();     // option #2: ERROR

  x->~X();
  ::operator delete(x);
}
Run Code Online (Sandbox Code Playgroud)

bol*_*lov 36

因为在构造函数启动之前X,该地址没有类型的对象.因此,取消引用x作为X类型或访问它的成员/方法将是未定义行为.

所以之间的主要区别x->X();(假设语法),并x->~X()是在第二情况下,你有一个对象,你可以调用一个(特殊)成员,如析构函数,而在第一种情况下,有没有对象还可以在其上调用方法(甚至是特殊方法 - 构造函数).

你可能会争辩说这条规则可能有例外,但最终会出现语法偏好问题,两种情况都存在不一致之处.使用当前语法,对构造函数的调用看起来不像是对构造函数的调用,在您提出的语法中,析构函数调用将具有对称性,但规则中的不一致性决定了何时可以取消引用/访问对象的方法.实际上,必须有一个异常允许在一个不是对象的东西上调用方法.那么你必须在标准的字母中严格定义一些不是对象的东西.

  • @DanielLangr不要道歉.**问一切!**如果它是主题,你可以在这里问:) (23认同)

das*_*ght 9

这是鸡蛋问题的变种.

您可以显式调用析构函数,就好像它们是成员函数一样,因为对象的实例已经存在.

您不能对构造函数执行相同的操作,因为您将调用它的实例需要存在,并由构造函数完全初始化.

唯一的例外是当您为对象分配了内存但尚未初始化实例时(即实例的内存已存在,但尚未初始化为实际实例).因此,您需要调用构造函数.这种情况是放置时new,您在"选项1"注释下显示的语法很有用.但是,这不是您在实例上执行的成员调用,因为该实例在进行该调用之前不可用.