是否可以让析构函数捕获异常然后重新抛出它们?
如果是这样,我该怎么做,因为 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/