【问题标题】:Is the destructor called when a delegating constructor throws?委托构造函数抛出时是否调用析构函数?
【发布时间】:2013-07-13 12:36:29
【问题描述】:

众所周知,如果构造函数抛出,那么所有完全构造的子对象都会以相反的顺序被销毁,包括成员数据和各种基类。但是,非委托构造函数不会调用析构函数。对于委托构造函数,当进入构造函数主体时,对象已经被构造,但构造仍在继续。因此,如果委托构造函数从其体内抛出异常,是否会调用类的析构函数?

class X
{
public:
    X();
    X(int) : X() { throw std::exception(); } // is ~X() implicitely called?
    ~X();
};

【问题讨论】:

  • X不是X的成员对象,为什么要调用它的析构函数呢?
  • @Praetorian:因为它已经完全由委托构造函数构造了;因为标准说它会。
  • 好问题,但重复,因此-1
  • 我真的不喜欢一个问题被认为是重复的,即使原始问题的提出方式很难通过搜索找到它。至少我希望正在寻找这个问题答案的人能在这里找到它。

标签: c++ exception c++11 constructor


【解决方案1】:

规则是析构函数被完全调用 构造的对象。该对象被认为是完全构造的 一旦任何构造函数完成,包括委托 构造函数(即使程序在另一个 构造函数)。

【讨论】:

  • 你能为此引用一个标准参考吗(尽管它很直观)?
  • @MarkB §15.2/2 "[...] 同样,如果对象的非委托构造函数已完成执行,并且该对象的委托构造函数以异常退出,则对象的析构函数将被调用。[...]"。
  • 我不确定我是否喜欢这种行为。
  • 有趣...这使得使用私有委托构造函数和公共委托构造函数来编写两阶段构造函数成为可能,仅用于异常安全问题。我想知道它是否能提供任何真正的优势。
  • @LokiAstari 没有其他意义(尽管我能理解您的担忧)。非委托构造函数已将类置于已定义状态(并且可能分配了需要释放的资源),因此必须调用析构函数。在委托构造函数中,构造函数主体中的代码处于一种不确定状态:它在构造函数中,但它不是类的基本构造的一部分。
【解决方案2】:

对象的生命周期开始于任何构造函数(即,在 委托情况下,最终目标构造函数)成功 完全的。出于 [C++03] §3.8 的目的,“构造函数调用 已完成”表示任何构造函数调用。这意味着一个 从委托构造函数的主体抛出的异常将导致 要自动调用的析构函数。

source.

here 是一篇关于委托构造函数的好文章,如果有人想阅读的话。

【讨论】:

  • 除非您引用的来源是该功能的早期提案。你引用的确切词没有进入最终标准,或者至少我找不到它们。你引用的“好文章”更多地是关于当你没有委托构造函数时该怎么做。
  • Corroborated by en.cppreference.com/w/cpp/language/throw > 如果在非委托构造函数成功完成后委托构造函数以异常退出,则调用该对象的析构函数。
猜你喜欢
  • 2013-01-01
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 1970-01-01
  • 2014-08-02
  • 2019-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多