C++異常處理(整理)

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);

例子:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章