c 異常處理機制示例及講解

2021-06-05 18:05:52 字數 3579 閱讀 5997

這兩天我寫了乙個測試c++異常處理機制的例子,感覺有很好的示範作用,在此貼出來,給c++異常處理的初學者入門。本文後附有c++異常的知識普及,有興趣者也可以看看。

下面的**直接貼到你的console工程中,可以執行除錯看看效果,並分析c++的異常機制。

#include "stdafx.h" 

#include

#include

#include 

// 記憶體洩露檢測機制

#define _crtdbg_map_alloc 

#ifdef _debug

#define new new(_normal_block, __file__, __line__)

#endif

// 自定義異常類

class

myexcepction  

// 拷貝建構函式

myexcepction( myexcepction& myexp)  

~myexcepction()  

// 獲取錯誤碼

intgeterrorid()  

private

:      

// 錯誤碼

intm_errorid;  

};  

intmain(

intargc, 

char

* argv)  

else

if( throwerrorcode == 119 )  

else

if( throwerrorcode == 120 )  

else

}  catch

( myexcepction*    pmyexcepction)  

catch

( myexcepction myexcepction)  

catch

(...)  

// 暫停

inttemp;  

std::cin >> temp;  

return

0;  

}

知識點: c++異常機制

一、 概述

c++自身有著非常強的糾錯能力,發展到如今,已經建立了比較完善的異常處理機制。c++的異常情況無非兩種,一種是語法錯誤,即程式中出現了錯誤的語句,函式,結構和類,致使編譯程式無法進行。另一種是執行時發生的錯誤,一般與演算法有關。

關於語法錯誤,不必多說,寫**時心細一點就可以解決。c++編譯器的報錯機制可以讓我們輕鬆地解決這些錯誤。

第二種是執行時的錯誤,常見的有檔案開啟失敗、陣列下標溢位、系統記憶體不足等等。而一旦出現這些問題,引發演算法失效、程式執行時無故停止等故障也是常有的。這就要求我們在設計軟體演算法時要全面。比如針對檔案開啟失敗的情況,保護的方法有很多種,最簡單的就是使用「return」命令,告訴上層呼叫者函式執行失敗;另外一種處理策略就是利用c++的異常機制,丟擲異常。

二、c++異常處理機制

c++異常處理機制是乙個用來有效地處理執行錯誤的非常強大且靈活的工具,它提供了更多的彈性、安全性和穩固性,克服了傳統方法所帶來的問題.

異常的丟擲和處理主要使用了以下三個關鍵字: try、 throw 、 catch 。

丟擲異常即檢測是否產生異常,在c++中,其採用throw語句來實現,如果檢測到產生異常,則丟擲異常。該語句的格式為:

throw 表示式;

如果在try語句塊的程式段中(包括在其中呼叫的函式)發現了異常,且拋棄了該異常,則這個異常就可以被try語句塊後的某個catch語句所捕獲並處理,捕獲和處理的條件是被拋棄的異常的型別與catch語句的異常型別相匹配。由於c++使用資料型別來區分不同的異常,因此在判斷異常時,throw語句中的表示式的值就沒有實際意義,而表示式的型別就特別重要。

try-catch語句形式如下 :

try

catch

(型別名 [形參名]) 

// 捕獲特定型別的異常

catch

(型別名 [形參名]) 

// 捕獲特定型別的異常

catch

(...)    

// 三個點則表示捕獲所有型別的異常

【範例1】處理除數為0的異常。該範例將上述除數為0的異常可以用try/catch語句來捕獲異常,並使用throw語句來丟擲異常,從而實現異常處理,實現**如**清單1-1所示。

// **清單1-1

#include//包含標頭檔案 

#include

double

fuc(

double

x, double

y) //定義函式

return

x/y;     

//否則返回兩個數的商

}  void

main()  

catch

(double

)             

//捕獲並處理異常

【範例2】自定義異常型別 (在本文開始的**中已經給出示範)

三、異常的介面宣告

為了加強程式的可讀性,使函式的使用者能夠方便地知道所使用的函式會丟擲哪些異常,可以在函式的宣告中列出這個函式可能丟擲的所有異常型別,例如:

void fun() 

throw( a,b,c,d);

這表明函式fun()可能並且只可能丟擲型別(a,b,c,d)及其子型別的異常。

如果在函式的宣告中沒有包括異常的介面宣告,則此函式可以丟擲任何型別的異常,例如:

void fun();

乙個不會丟擲任何型別異常的函式可以進行如下形式的宣告:

void fun() thow();

五、異常處理中需要注意的問題

1. 如果丟擲的異常一直沒有函式捕獲(catch),則會一直上傳到c++執行系統那裡,導致整個程式的終止

2. 一般在異常丟擲後資源可以正常被釋放,但注意如果在類的建構函式中丟擲異常,系統是不會呼叫它的析構函式的,處理方法是:如果在建構函式中要丟擲異常,則在丟擲前要記得刪除申請的資源。

3. 異常處理僅僅通過型別而不是通過值來匹配的,所以catch塊的引數可以沒有引數名稱,只需要引數型別。

4. 函式原型中的異常說明要與實現中的異常說明一致,否則容易引起異常衝突。

5. 應該在throw語句後寫上異常物件時,throw先通過copy建構函式構造乙個新物件,再把該新物件傳遞給 catch. 

那麼當異常丟擲後新物件如何釋放?

異常處理機制保證:異常丟擲的新物件並非建立在函式棧上,而是建立在專用的異常棧上,因此它才可以跨接多個函式而傳遞到上層,否則在棧清空的過程中就會被銷毀。所有從try到throw語句之間構造起來的物件的析構函式將被自動呼叫。但如果一直上溯到main函式後還沒有找到匹配的catch塊,那麼系統呼叫terminate()終止整個程式,這種情況下不能保證所有區域性物件會被正確地銷毀。

6. catch塊的引數推薦採用位址傳遞而不是值傳遞,不僅可以提高效率,還可以利用物件的多型性。另外,派生類的異常撲獲要放到父類異常撲獲的前面,否則,派生類的異常無法被撲獲。

7. 編寫異常說明時,要確保派生類成員函式的異常說明和基類成員函式的異常說明一致,即派生類改寫的虛函式的異常說明至少要和對應的基類虛函式的異常說明相同,甚至更加嚴格,更特殊。

c 異常處理機制示例及講解

這兩天我寫了乙個測試c 異常處理機制的例子,感覺有很好的示範作用,在此貼出來,給c 異常處理的初學者入門。本文後附有c 異常的知識普及,有興趣者也可以看看。下面的 直接貼到你的console工程中,可以執行除錯看看效果,並分析c 的異常機制。include stdafx.h include incl...

c 異常處理機制示例及講解

下面的 直接貼到你的console工程中,可以執行除錯看看效果,並分析c 的異常機制。include stdafx.h include include include 記憶體洩露檢測機制 define crtdbg map alloc ifdef debug define new new norma...

c 異常處理機制示例及講解

這兩天我寫了乙個測試c 異常處理機制的例子,感覺有很好的示範作用,在此貼出來,給c 異常處理的初學者入門。本文後附有c 異常的知識普及,有興趣者也可以看看。下面的 直接貼到你的console工程中,可以執行除錯看看效果,並分析c 的異常機制。include stdafx.h include incl...