c++ - 在析构函数中捕获异常

标签 c++ exception destructor

是否可以让析构函数捕获异常然后重新抛出它们?
如果是这样,我该怎么做,因为 try 语句没有明确的位置?

基本上,我想理想地做:

CMyObject::~CMyObject()  
{
    catch(...)    // Catch without a try.  Possible?
    {
        LogSomeInfo();
        throw;  // re-throw the same exception
    }
    // Normal Destructor operations
}

背景
我有一个大型、复杂的应用程序,它在某处抛出未处理的异常。 我无法轻松访问 main 或顶级消息泵或类似的东西,因此没有容易的地方来捕获所有未处理的异常。

我认为任何未处理的异常都必须在堆栈展开时通过一堆析构函数。所以,我正在考虑在析构函数中分散一堆 catch 语句。然后至少我会知道抛出异常时有哪些对象在起作用。但我不知道这是否可行或可取。

最佳答案

编辑:您可以使用 std::uncaught_exception检查当前是否抛出异常(即是否由于异常而正在进行堆栈展开)。无法捕获该异常或以其他方式从您的析构函数访问它。因此,如果您的日志记录不需要访问异常本身,您可以使用

CMyObject::~CMyObject()  
{
  if(std::uncaught_exception()) {
    LogSomeInfo(); // No access to exception.
  }
  // Normal Destructor operations
}

请注意,这个问题是在 2013 年提出的,同时 std::uncaught_exception 被替换为 std::uncaught_exceptions (注意额外的 s最后)返回一个int。有关基本原理,请参阅 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4152.pdf ,所以如果你使用的是 C++17,你应该更喜欢新版本。上述论文还解释了为什么旧的 std::uncaught_exception 在某些情况下无法按预期工作。


另一个选项可能是 std::set_terminate .如果您希望在未捕获异常并即将终止程序时调用方法,这将很有用。在终止处理程序中,我通常会在最终终止程序之前打印一些关于异常的信息和它来自哪里的(解构的)回溯到我的日志文件。这是特定于编译器和系统的,但它是一个真正的 helper ,因为如果您编写服务器进程并且通常日志文件就是您从操作中获得的全部内容,它可以节省大量时间。

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

相关文章:

c# - 将错误代码大量转换为异常

android - NfcA.transceive(byte[] data) 抛出 TagLostException

c++ - move 构造函数不调用析构函数?

c++ - 循环和调用堆栈

c++ - 如何在其父类中调用子类?

c++ - 二维数组打印元素总和

c++ - 如何为我的程序修复这个小的内存泄漏?

.net - ./在我使用 OpenFileDialog 时更改目标

java - 如何在通过 DocumentBuidlerFactory 创建新的 xml 文件时生成 ParserConfigurationException

c++ - 如何在 package.preload 函数中破坏 C++ 类