是什麼這些的try-catch塊的實用性和行爲的差異?我什麼時候會更喜歡一種形式?
int f() {
try {
...
} catch(...) {
...
}
}
int f() try {
...
} catch (...) {
...
}
是什麼這些的try-catch塊的實用性和行爲的差異?我什麼時候會更喜歡一種形式?
int f() {
try {
...
} catch(...) {
...
}
}
int f() try {
...
} catch (...) {
...
}
如果整個身體必須進入異常塊,我傾向於更喜歡第二種形式,因爲它更容易閱讀(例如縮小一級)。
但是,造成這種差異的主要地方是構造函數。試想一下:
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);
}
有些人會說,不捕獲異常使程序崩潰,你可以得到一個核心轉儲,以幫助調試。雖然這在調試模式下可能很有用,因爲它可以幫助調試器將您指向引發異常的確切代碼行,我喜歡發佈不會崩潰的程序,並且可以向用戶顯示一條消息,說明一個錯誤報告已提交。
函數try-catch塊僅在構造函數中有用,即使如此,它也不是很有用。最好忘記它們的存在。
原則上,它們*可能*在構造函數中有一些用處。但是,我從來不必使用它們。 –
+1在構造函數中使用FTB的詳細信息。但是,你可以爲初始化列表添加一些實際的語法示例嗎? –
+1在初始化程序列表中提到捕獲異常。 – zennehoy
@KerrekSB:爲語法添加註釋和請求示例。 –