【问题标题】:cleaning up after an exception [duplicate]异常后清理[重复]
【发布时间】:2013-12-22 05:25:49
【问题描述】:

我有这样的代码:

class myclass
{
     myclass()
     {
        // doing some init here
      }
     ~myclass()
     {
        // doing some important clean up here
     }
     void Do()
     {
          //    doing some work which may throw exception
      }
}

我就是这样使用这个类的:

MyFunction()
{
    myclass mc;
    mc.do();
 }

我的问题是:

如果do函数出现异常,会发生什么?是否调用了 myclass 的析构函数?

如果不是,处理此类情况的最佳方法是什么?假设我没有源代码,并且我确信析构函数中发生了什么。

【问题讨论】:

  • C++ 保证会调用析构函数,所以你不必担心。
  • 好问题。已经回答了。
  • @FrédéricHamidi:仅在处理异常时。
  • @FrédéricHamidi:确实;因此,一般不保证。 (抱歉,我的意思是“只保证”,而不是“只叫”——我应该更具体些)。

标签: c++ exception


【解决方案1】:

如果do函数出现异常,会发生什么?

如果你有任何处理程序,它将被处理。

是否调用了 myclass 的析构函数?

是的,当然。标准引用了这个::

任何存储持续时间的对象,其初始化或销毁 被异常终止时会为所有人执行析构函数 其完全构造的子对象(不包括 一个类似联合的类),也就是说,对于其主体的子对象 构造函数(12.6.2)已完成执行且析构函数已 尚未开始执行。同样,如果非委托构造函数 对于一个对象已经完成执行和一个委托构造函数 该对象以异常退出,该对象的析构函数将是 调用。如果对象是在新表达式中分配的,则匹配 释放函数 (3.7.4.2, 5.3.4, 12.5),如果有的话,被调用到 释放对象占用的存储空间。

整个过程称为“堆栈展开”:

为自动构造的对象调用析构函数的过程 从 try 块到 throw 表达式的路径称为“堆栈” 放松。”如果在堆栈展开期间调用的析构函数以 一个例外,调用 std::terminate (15.5.1)。

C++11 15.5.1 std::terminate() 函数[except.terminate]

2 ... 在没有找到匹配处理程序的情况下,它是 实现定义堆栈之前是否展开 std::terminate() 被调用。

【讨论】:

    【解决方案2】:

    如果异常在某处被捕获,那么 stack unwinding 将保证为此对象调用析构函数(通常,所有因异常而超出范围的自动变量)。这是一个非常重要的保证,没有它我们就无法使用像RAII 这样的技术来编写异常安全的代码。

    如果异常没有被捕获,那么程序将被终止,并且取决于实现是否首先解除堆栈。如果在这种情况下彻底销毁对象很重要,那么一种选择是在对象范围之外捕获并重新抛出异常。

    如果程序以其他方式结束,例如通过调用exit()terminate(),或接收未处理的信号,堆栈将不会被展开。如果您在这些情况下需要彻底销毁,那么事情就会变得一团糟。

    【讨论】:

      【解决方案3】:

      C++ 不像许多其他语言那样具有显式的“finally”子句,而是依赖于“RAII”,它本质上是一种使用作用域“自动”变量的技术,并依赖于它们的析构函数将在超出范围的适当时机。

      在您的情况下,即使mc.do() 抛出异常,也会调用 myclass 的析构函数。在许多此类“关闭”问题中,您放在作用域块顶部的对象是一个仅用于在终止时调用析构函数的类。

      “D”语言带有特殊的闭包语法。已经有人尝试用 C++ 和 lambda 来编写库,虽然我认为它们还不是 C++ 的正式部分,但它肯定比现在更容易编写。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-06
        • 2014-01-06
        • 1970-01-01
        相关资源
        最近更新 更多