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 *。
數組也是一種類型,數組並不等價於指針,這點已在《數組和指針絕不等價,數組是另外一種類型》和《數組在什麼時候會轉換為指針》中進行了詳細講解。