c++ - 在析构函数中检测事件异常

标签 c++ exception destructor raii

我有一个使用 RAII 进行清理的类,以防出现问题。这意味着该类包含一个标志,告诉它工作是否已完成,如果在调用构造函数时未设置此标志,它将执行清理任务并生成日志消息。现在我希望这个类变得更加聪明,即它应该发现错误是否发生,因为工作被中止(即抛出异常并且调用析构函数)或者因为有人滥用这个类并且从未实际上完成了工作。这意味着我必须在析构函数中找出异常是否处于事件状态。如果找到一个,我会生成一条日志消息,可能会打印异常的内容,然后重新抛出它。我猜是这样的。

Foo::~Foo () {
  try { /* do not know what to put here */ }
  catch( const std::exception & ex ) {
     // produce error in log
     throw;
  }
  catch( ... ) {
    // produce some other log message
    throw;
   }
}

但是我不确定这是否可行,因为在调用析构函数之前异常已经处于事件状态并且不是源自 try block 。此外,我在析构函数中使用了 throw; 并在此时抛出异常是一个非常糟糕的主意。所以我不会这样做,除非标准明确保证这种情况是该规则(我不知道)的异常(exception)(没有双关语)。

那么这是否可能,或者我应该以其他方式处理这种情况?

最佳答案

您可以使用 std::uncaught_exception() 如果已抛出异常但 catch 尚未处理它,则返回 true。您可以在析构函数中使用此检查来决定它应该做什么或不应该做什么。

请注意,良好的编程指南通常规定让析构函数在不同情况下表现出明显不同通常不是一个好主意。所以使用这个功能,但不要滥用它。一个常见的用途是拥有一个仅在没有事件的未捕获异常(此函数返回 false)时才抛出的析构函数。但这种行为通常不是好的设计。如果条件严重到需要异常(exception),那么它可能不应该被忽略。而且析构函数无论如何都不应该抛出异常。

例子:

Foo::~Foo()
{
    if (std::uncaught_exception()) 
    {
        std::cerr << "Warning: Can't cleanup properly" << std::endl;
        return;
    }
    else
    {
        // ...
    }
}

关于c++ - 在析构函数中检测事件异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5511568/

相关文章:

c++ - 在退出或程序结束时执行函数

c++ - 初始化程序列表不适用于 Visual Studio 2012 中的 vector ?

c++ - 使用数组中的值,包含多个 vector

Python 定义一个迭代器类,失败并返回 "iter() returned non-iterator of type ' Fib'"

java - 带有消息格式参数的可抛出构造函数

Java接口(interface)抛出异常最佳实践

c++ - 当你有一个二维数组(在 C++ 中)时,调用析构函数的正确方法是什么?

c++ - 为什么即使删除了析构函数,我仍然可以创建匿名 union ?

c++ - 在 C++ 中使用 std::ifstream 读取 ASCII 文本文件

c++ - 取消装饰窗口的跨平台解决方案?