删除的构造函数在初始化器中调用

时间:2018-08-19 20:11:03

标签: c++

是的,我知道析构函数很重要,但是在这种情况下,Foo和Bar都将成为单例。出于调试目的,我想确保从不删除单例对象(我不小心使这种情况发生了一次)。

class Bar {
public:
    Bar();
    ~Bar() = delete;
}
class Foo {
public:
    Foo();
    Bar b;
}

所有构造函数和析构函数主体均为空。所以cpp看起来就像

Foo::Foo() {
}

此代码会导致我没有想到的错误。我会因为在Foo的destructor方法中没有析构函数而感到沮丧,但是我在构造函数上遇到了错误。出于某种原因,编译器表示正在引用已删除的函数。为什么它在构造函数中对此很在意?

1 个答案:

答案 0 :(得分:1)

Bar b;作为类成员意味着b必须有一个可访问的析构函数。

这样做的理由是,在构建Foo之后但在构建b之前,如果在构建Foo期间抛出异常,则可以销毁它。完成。

不幸的是,即使您的代码没有任何可能的例外,该规则仍然有效。您将不得不重新设计类布局,以使单例不直接作为其他类的数据成员包括在内,即使它们也是单例也是如此。

参考文献:

C ++ 17 [class.base.init] / 12:

  

在非委托构造函数中,可能会调用类类型的每个可能构造的子对象的析构函数。 [注:此规定确保了在抛出异常的情况下可以为完全构造的子对象调用析构函数(18.2)。 —尾注]

也[class.dtor] /12.4:

  

如果潜在调用的析构函数被删除或无法从调用上下文访问,则程序格式错误。