2011-01-07 33 views
1

香草薩特在他的文章http://www.gotw.ca/gotw/047.htm 指出,我們不能在desturctor功能使用uncaught_exception,爲什麼不能在dtor中使用uncaught_exception?

// Why the wrong solution is wrong 
// 
U::~U() { 
    try { 
    T t; 
    // do work 
    } catch(...) { 
    // clean up 
    } 
} 

如果U形物體被摧毀,由於期間的異常傳播堆棧展開,T ::〜T將失敗儘管它可以安全地使用「可能拋出的代碼」路徑。

,但我寫了一個測試程序,以及T ::〜T IN其實並沒有使用「代碼會拋出異常」

#include <exception> 
#include <iostream> 
using namespace std; 

class T { 
    public: 
    ~T() { 
    if(!std::uncaught_exception()) 
    { 
    cout<<"can throw"<<endl; 
    throw 1; 
    } else 
    { 
    cout<<"cannot throw"<<endl; 
    } 
} 


}; 

struct U 
{ 
~U() { 
    try 
    { 
    T t; 
    } 
    catch(...) 
    { 
    } 
} 
}; 

void f() 
{ 
    U u; 
    throw 2; 
} 

int main() 
{ 
    try 
    { 
     f(); 
    } 
    catch(...) 
    {} 
} 

輸出是: 不能扔

我錯過什麼?

感謝

回答

3

這正是他的意思:「將無法拋出」是指「將不會拋出,因爲它會認爲投擲是不是在目前情況下的安全」(「會崩潰」 ;這裏失敗意味着不會發生)。因爲析構函數被稱爲堆棧的一部分 - 由異常引起的反繞std::uncaught_exception()返回true,並且T::~T()不使用可能拋出的代碼(用他的話來說:T::~T將無法​​使用「可能拋出的代碼」路徑即使它安全地可以),因爲它認爲它不應該扔。關鍵是,因爲T的包裹在try{}catch(...){}區塊它是安全拋出,即使有一個未決的例外。

+0

感謝您的詳細解釋conio – camino 2011-01-07 10:04:20