在C ++中有什么好方法可以在析构函数中检测它是否在堆栈展开期间运行,因为抛出异常而不是正常退出触发析构函数的作用域?我想知道,以便我可以创建一个具有一些清理代码的类,该代码始终在正常退出时运行,但在发生异常时跳过。
答案 0 :(得分:19)
std::uncaught_exception()
(在<exception>
中定义)将在析构函数中告诉您是否因为异常而被调用:
class A
{
public:
~A()
{
if (std::uncaught_exception()) {
// Called because of an exception
} else {
// No exception
}
}
};
答案 1 :(得分:5)
可能this文章会对您有所帮助。本文将向您展示std :: uncaught_exception()的问题,并包含如何处理析构函数中的异常的建议。
答案 2 :(得分:1)
除非你有充分的理由,否则不要这样做。堆栈展开是一种语言特性,try
块中的所有自动对象都将被强制解除分配,以便它们内部的资源有机会释放。
您希望在堆栈展开期间在dtor中跳过清理,这会绕过它的初衷。而你将面临资源泄漏的风险。
示例强> 的
class CDBConnection
{
public:
CDBConnection()
{
m_db.open();
}
~CDBConnection()
{
if (!std::uncaught_exception())
m_db.close();
// if this is called during a stack unwinding,
// your DB connection will not be closed for sure.
// That's a resource leakage.
}
//..
private:
DB m_db;
};
void main()
{
//..
try
{
// code that may throw
CDBConnection db;
//..
}
catch(const CDBException& exp)
{
// properly handle the exception
}
}
答案 3 :(得分:0)
这是我能想到的一种方式,但它似乎很笨拙:
{
myCleanupClass unwindAction;
try {
// do some work which may throw exception.
} catch (...) {
unwindAction.disableDestructorWork();
throw;
}
}