如果失败的析构函数不能抛出异常该怎么办

sky*_*oor 5 c++

我注意到你不能在析构函数中抛出异常.所以我的问题是如果析构函数失败我应该怎么做.

另一个问题是,在什么情况下析构函数可能会失败?

非常感谢

Ste*_*sop 14

忽略错误.

如果例如类包装某种输出,则析构函数可能会"失败",并且析构函数会刷新并关闭该输出.写入数据可能会失败.您的选择是终止程序,或捕获异常,忽略错误,然后返回.通常正确的设计是忽略它.

在我的示例中,该类还应该具有"close_and_flush"函数,如果用户想要知道它是否成功,则可以在对象销毁之前调用该函数.如果您的类的用户不关心操作是否失败,那么您也不会,并且您可以安全地抑制该异常.

然后用户可以编写如下代码:

{
    OutputObject OO;
    write some stuff to OO, might throw;
    do more things, might throw;
    try {
        OO.flush_and_close();
    } catch (OutputException &e) {
        log what went wrong;
        maybe rethrow;
    }
}
Run Code Online (Sandbox Code Playgroud)

或这个:

try {
    OutputObject OO;
    write some stuff to OO, might throw;
    do more things, might throw;
    OO.flush_and_close();
} catch (AnyOldException &e) {
    log what went wrong;
    maybe rethrow;
}
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,在没有用户显式刷新的情况下,对象将被销毁的唯一时间是,如果其他东西抛出异常并且在堆栈展开期间对象被销毁.因此,他们已经知道他们的操作已经失败,如果有必要,他们可以回滚交易或其他任何他们必须做的事情来应对失败.


Ale*_*ler 8

设计你的课程,他们的设计不能失败.如果d'tor中的某些东西可能会抛出一个异常,那就把它抓住,然后吞下它(或者按照你喜欢的方式处理它,但不要重新抛出它).


小智 6

我不同意析构函数应该"设计成不会失败"的想法 - 当然它们可能会失败.例如,在析构函数中调用fclose()可能会失败.现在问题是该怎么办呢?在我看来,有两种选择:

  • 忽略它.这具有简单的优点,但你永远不会知道失败发生,这可能意味着隐藏错误.

  • 记录下来.这样做的问题是,无法保证写入日志也不会失败,或触发其他一些问题.

如果这让你没有明智的话,那对我来说也是一样的!基本上,没有完美的解决方案.您需要根据具体情况从上述两个选项中进行选择.决定的一种方法是思考"如果这是C代码(没有析构函数),我该怎么办?" - 如果你忽略C中的问题,也可以在C++中忽略它,