1.異常機制的語法
try {
try-fields //我們程序執行要實現某種功能所必需的語句
throw exception-object;//利用條件判斷,當某種條件滿足時拋出異常表達式
}
catch (exception-[object | pointer | reference] e) { //捕獲異常並進行異常處理,不同的異常表達式類型需要不同的catch塊,
catch-fields
}
catch (...) { //捕獲異常並進行異常處理,這裏面的...是可以捕捉任意類型的異常
catch-fields
}。
例1:除法運算過程中的除數爲零的判斷。
沒有異常處理的程序:
帶異常處理的程序:
2.異常機制分析
★try:診斷異常代碼;
try{
//可能出現異常的情況
}
☆可能出現異常的三種情況:
①可執行語句;②一個函數調用;③一個函數調用另一個函數;
★throw:拋出錯誤信息;
判斷條件檢查
條件滿足 throw 參數(只有一個,可以是任何類型,甚至是一個對象)
例:
if(分母==0){
throw 參數(只有一個,可以是任何類型,甚至是一個對象)
}
★catch:捕獲異常信息;
catch(參數類型參數)//只能一個參數,形參可以被省略,但省略後不能輸出異常信息,依然可以捕獲;
{ 異常處理 }
注意:catch塊不能訪問try塊裏面定義的臨時變量。
★注意:如果throw拋出了異常,異常類型如果與catch塊後面的類型匹配,catch塊內的代碼將會被執行,在try語句後面可以有多個catch塊,程序會尋找第一個相匹配的catch塊,實行catch塊的語句代碼,然後跳到最後一個catch塊的下一行代碼,如果沒有匹配的catch塊,則異常返回上一層try-catch語句,如果沒有相應的catch發現,程序將會終結。
★try-throw-catch的三種寫法:
//第一種:(操作放在try塊中進行判斷)
//第二種:(把操作放到函數體中判斷並實現)
//第三種:函數嵌套
函數嵌套的異常捕捉例子:
3.異常處理的問題------棧展開(Stack unwinding):
★定義:如果一個函數裏產生異常,那麼這個函數將會被終結,並且本地變量(棧上的變量)會被釋放。但是如果有指針且動態分配了內存,那麼棧上的指針將會被釋放,而指針指向的堆內存沒有被釋放,這時會發生內存泄漏。在這種情況下,爲了避免內存泄漏,必須把指針拋給它的上一層調用者,讓它來釋放這塊堆內存。我們可以把這個指針封裝到一個錯誤消息類裏面去,然後拋出這個類的對象(構造函數構造的臨時對象),爲了避免臨時對象的生成,我們在catch塊裏用這個類的引用做參數。
例:
func(){
int a=5; //在棧上聲明的;
int b=8; //在棧上聲明的;
char* p=new char[100] //p在棧上,p指向的內存在堆上;
//throw "exception"; //會發生內存泄漏;
...
...
}
▲爲了避免內存泄露,我們需要將指針拋出。我們把指針封裝在一個錯誤類裏面,然後把對象拋出,爲了避免拷貝構造,我們傳一個對象的引用。
例:
▌不捕獲異常(Uncaught exception):
★定義:如果一個異常沒有被catch住,或者沒有寫catch塊,這種情況就叫不捕獲異常。如果一個異常沒有被捕獲住,則會終結(terminate)函數。
例:
重設異常的兩個函數:From MSDN
set_terminate():Installs your own termination routine to be called by terminate.
set_new_handler( ):Installs a user function that is to be called when operator new fails in its attempt to allocate memory.
new_handler set_new_handler(new_handler _Pnew);
例子: