人们强烈反对从析构函数中抛出异常。以这个答案为例。我想知道是否std::uncaught_exception()
可以用于便携式检测我们是否由于其他一些异常而处于展开堆栈的过程中。
我发现自己故意在析构函数中抛出异常。提到两个可能的用例:
- 一些涉及刷新缓冲区的资源清理,因此失败可能表示输出被截断。
- 销毁持有
std::exception_ptr
可能包含在不同线程中遇到的异常的对象。
简单地忽略这些特殊情况是完全错误的。并且有可能通过抛出异常,一些异常处理程序可能能够提供比析构函数本身写入的更有用的上下文信息std::cerr
。此外,为所有失败的断言抛出异常是我的单元测试方法的重要组成部分。在这种情况下,错误消息后跟被忽略的错误条件将不起作用。
所以我的问题是,是否可以抛出异常,除非正在处理另一个异常,还是有理由不这样做?
把它放在代码中:
Foo::~Foo() {
bool success = trySomeCleanupOperation();
if (!success) {
if (std::uncaught_exception())
std::cerr << "Error in destructor: " << errorCode << std::endl;
else
throw FooOperationFailed("Error in destructor", errorCode);
}
}
据我所知,这应该是安全的,并且在许多情况下比根本不抛出异常要好。但我想验证一下。