try{
// 可能拋出異常的語句
}catch(exceptionType variable){
// 處理異常的語句
}
exceptionType variable
,這節就來詳細分析一下。exceptionType
是異常類型,它指明了當前的 catch 可以處理什麼類型的異常;variable
是一個變量,用來接收異常信息。當程序拋出異常時,會創建一份數據,這份數據包含了錯誤信息,程序員可以根據這些信息來判斷到底出了什麼問題,接下來怎麼處理。exceptionType variable
和函數的形參非常類似,當異常發生後,會將異常數據傳遞給 variable 這個變量,這和函數傳參的過程類似。當然,只有跟 exceptionType 類型匹配的異常數據才會被傳遞給 variable,否則 catch 不會接收這份異常數據,也不會執行 catch 塊中的語句。換句話說,catch 不會處理當前的異常。
try{
// 可能拋出異常的語句
}catch(exceptionType){
// 處理異常的語句
}
try{ //可能拋出異常的語句 }catch (exception_type_1 e){ //處理異常的語句 }catch (exception_type_2 e){ //處理異常的語句 } //其他的catch catch (exception_type_n e){ //處理異常的語句 }當異常發生時,程序會按照從上到下的順序,將異常類型和 catch 所能接收的類型逐個匹配。一旦找到類型匹配的 catch 就停止檢索,並將異常交給當前的 catch 處理(其他的 catch 不會被執行)。如果最終也沒有找到匹配的 catch,就只能交給系統處理,終止程序的運行。
#include <iostream> #include <string> using namespace std; class Base{ }; class Derived: public Base{ }; int main(){ try{ throw Derived(); //拋出自己的異常類型,實際上是創建一個Derived類型的匿名對象 cout<<"This statement will not be executed."<<endl; }catch(int){ cout<<"Exception type: int"<<endl; }catch(char *){ cout<<"Exception type: cahr *"<<endl; }catch(Base){ //匹配成功(向上轉型) cout<<"Exception type: Base"<<endl; }catch(Derived){ cout<<"Exception type: Derived"<<endl; } return 0; }運行結果:
在 catch 中,我們只給出了異常類型,沒有給出接收異常信息的變量。本例中,我們定義了一個基類 Base,又從 Base 派生類出了 Derived。拋出異常時,我們創建了一個 Derived 類的匿名對象,也就是說,異常的類型是 Derived。
catch(Derived)
捕獲,但是從輸出結果可以看出,異常提前被catch(Base)
捕獲了,這說明 catch 在匹配異常類型時發生了向上轉型(Upcasting)。
#include <iostream> using namespace std; int main(){ int nums[] = {1, 2, 3}; try{ throw nums; cout<<"This statement will not be executed."<<endl; }catch(const int *){ cout<<"Exception type: const int *"<<endl; } return 0; }運行結果:
int [3]
,但是 catch 中沒有嚴格匹配的類型,所以先轉換為int *
,再轉換為const int *
。
數組也是一種類型,數組並不等價於指針,這點已在《數組和指針絕不等價,數組是另外一種類型》和《數組在什麼時候會轉換為指針》中進行了詳細講解。