2011-11-01 40 views
1

在C++中,如何在我的析构函数体中检测堆栈是否因抛出异常而解开?一旦检测到,我可以获得对活动异常的引用吗?如何在析构函数中检测异常是否处于活动状态?

我问,因为我想添加一些调试代码,解释为什么会出现某种情况以及是否由于例外。

+3

这听起来像是现在是阅读[GoTW#47](http://www.gotw.ca/gotw/047.htm)的好时机。 –

+0

建设可能会失败,但破坏永远不会。在对象销毁期间没有任何异常处理机制。 – Mahesh

+1

@Mahesh我认为你误解了这个问题。它不是关于析构函数中的异常处理,而是关于检测析构函数是否因对象的周围范围中抛出的异常而被调用。 –

回答

4

std::uncaught_exception告诉你堆栈是否因抛出异常而解开,这就是你所问的。

但是,它并没有告诉你你可能想知道的内容:你调用它的析构函数的对象是否在正在解开的堆栈的一部分中,或者是正常销毁的那部分堆栈由于非异常退出一些其他的析构函数是开卷的一部分下方的范围:

struct A { 
    ~A(); 
}; 

struct B { 
    ~B(); 
} 

int main() { 
    try { 
     A a; 
     throw 1; 
    } catch(...) {} 
} 

A::~A() { 
    std::uncaught_exception(); // true 
    B b; 
} 

B::~B() { 
    std::uncaught_exception(); // also true, but "b" isn't being "unwound", 
     // because ~A() returned, it didn't throw. 
} 

相反的是DeadMG和XEO说,你不能去尚未捕获的异常的参考。不带操作数的throw会重新抛出“当前处理的异常”,也就是说,您所在的catch处理程序或其捕获处理程序已调用您的异常。它不会重新抛出未捕获的异常。

+0

这就是我认为扔不工作,感谢确认。 – WilliamKF

+0

“_whether **由于异常被抛出,正在解除**堆栈_”嗯,有时确实有两个**堆栈:一个解开,一个对象的析构函数使用的堆栈被破坏**因为**的展开。 – curiousguy

0

在C++中,如何检测我的析构函数体是否由于引发异常而导致堆栈被解除?

不是。

一旦检测到,我可以获得对活动异常的引用吗?

0

有一个std::uncaught_exception()功能。但是,尝试访问异常对象可以做的唯一有用的事情是重新抛出它并尝试捕获它。一般来说,你绝不应该从任何析构函数中抛出异常。

+0

如何重新抛出未被捕获的异常? – WilliamKF

+0

'try {throw; } catch(std :: exception const&e){/ *处理它* /}' – Xeo

+0

“_There是一个std :: uncaught_exception()函数._”不回答问题。 – curiousguy

相关问题