2011-11-02 68 views

回答

6

如果整個身體必須進入異常塊,我傾向於更喜歡第二種形式,因爲它更容易閱讀(例如縮小一級)。

但是,造成這種差異的主要地方是構造函數。試想一下:

Foo::Foo() 
try : member_with_throwing_constructor(initial_value) 
{ 
} 
catch (...) 
{ 
    // will process exceptions thrown by `member_with_throwing_constructor` 

    // this will be added by the compiler if you 
    // don't finish by a `throw ...` statement. 
    throw; 
} 

Foo::Foo() 
    : member_with_throwing_constructor(initial_value) 
{ 
    try 
    { 
    } 
    catch (...) 
    { 
     // does not catch exceptions thrown in constructor 
     // of `member_with_throwing_constructor`. 
    } 
    // can keep processing if `catch` handler does not `return` or `throw`. 
} 

這兩段代碼有完全不同的行爲。第一個將捕獲數據成員構造函數中引發的異常(通常通過初始化程序列表,但也應用默認構造函數),並會自動重新引發異常,因爲無法安全地創建實例。第二種形式不包括數據成員初始化,並允許您選擇是否保留該對象。

我還想在main()中添加全局try-catch來幫助調試未捕獲的異常。下面的代碼片段:

int main (int, char **) 
try 
{ 
    // main program... 
} 
catch (const std::exception& error) 
{ 
    std::cerr << "Uncaught exception: '" << error << "'." << std::endl; 
    return (EXIT_FAILURE); 
} 
catch (...) 
{ 
    std::cerr << "Uncaught exception of unknown type." << std::endl; 
    return (EXIT_FAILURE); 
} 

有些人會說,不捕獲異常使程序崩潰,你可以得到一個核心轉儲,以幫助調試。雖然這在調試模式下可能很有用,因爲它可以幫助調試器將您指向引發異常的確切代碼行,我喜歡發佈不會崩潰的程序,並且可以向用戶顯示一條消息,說明一個錯誤報告已提交。

+0

+1在構造函數中使用FTB的詳細信息。但是,你可以爲初始化列表添加一些實際的語法示例嗎? –

+0

+1在初始化程序列表中提到捕獲異常。 – zennehoy

+0

@KerrekSB:爲語法添加註釋和請求示例。 –

2

函數try-catch塊僅在構造函數中有用,即使如此,它也不是很有用。最好忘記它們的存在。

+0

原則上,它們*可能*在構造函數中有一些用處。但是,我從來不必使用它們。 –