构造函数抛出异常时运行哪些析构函数?

时间:2012-04-18 15:34:16

标签: c++ constructor exception-handling destructor

在C ++中,如果构造函数抛出异常,那么运行什么析构函数?

特别是,如果异常是在初始化列表或正文中,它会有什么不同吗?

另外,继承和成员呢?据推测,所有完工的建筑都被破坏了。如果只建造了一些成员,那么只有那些被破坏吗?如果有多个继承,那么所有已完成的构造函数都会被破坏吗?虚拟继承会改变什么吗?

3 个答案:

答案 0 :(得分:68)

如果构造函数抛出异常,会运行哪些析构函数?

在该范围内完全创建的所有对象的析构函数。

如果异常是在初始化列表或正文中,它会有什么不同吗?

所有已完成的物体都将被毁坏 如果构造函数从未被完全调用,则对象从未被构造,因此无法被破坏。

继承和成员怎么样?据推测,所有完工的建筑都被破坏了。如果只建造了一些成员,那么只有那些被破坏吗?如果有多个继承,那么所有已完成的构造函数都会被破坏吗?虚拟继承会改变什么吗?

所有已完成的结构都会被破坏。是的,只有完全创建的对象才会被破坏。

好读:

<强> Constructor Failures by Herb Sutter

特别喜欢他解释的部分:

  

从生物学的角度来看,构思开始了 - 但是尽管做了最好的努力,但随后出现了流产 - 构造函数从未达到过期(开始)。

     

顺便说一句,这就是为什么如果构造函数没有成功就永远不会调用析构函数 - 没有什么可以破坏的。 “它不会死,因为它永远不会存在。”请注意,这使得短语“一个构造函数抛出异常的对象”真的是矛盾的。这样的事情甚至比一个前对象还要少......它从来没有生存过,从来没有,从未放过它的第一个。

答案 1 :(得分:18)

  

在C ++中,如果构造函数抛出异常,那么运行什么析构函数?

所有具有构造函数的对象都运行完毕。

  

特别是,如果异常是在初始化列表或正文中,它会有什么不同吗?

没有。在异常之前完全构造的所有成员将运行其析构函数。在施工期间投掷的成员和所有其他非构造成员将让他们的析构函数运行。成员构造的顺序是明确定义的,因此你知道如果你知道异常抛出点会发生什么。

  

另外,继承和成员呢?

同样的规则适用。

  

据推测,所有已完成的建筑都会被毁坏。

  

如果只构建了一些成员,那么只做那些被破坏的成员吗?

  

如果有多个继承,那么所有已完成的构造函数都会被破坏吗?

  

虚拟继承会改变什么吗?

没有。
但请注意:虚拟继承确实会影响构造函数的调用顺序。如果您不熟悉订单的定义方式,那么在您查找确切的规则之前,这可能不直观。

答案 2 :(得分:4)

由于构造函数而在本地范围内创建的任何对象都将 被毁坏。运行时处理在堆栈中回调,调用 析构函数,直到它找到一个处理程序。

如果从构造函数抛出异常,则抛出所有的析构函数 将调用完全构造的子对象。另外,如果 构造函数是new表达式的一部分,是适当的位置 删除操作符将被调用(如果存在)。