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語句來丟擲異常,從而實現異常處理,實現**如**如下:
#include//包含標頭檔案
#include
double fuc(double x, double y) //定義函式
return x/y; //否則返回兩個數的商
} void main()
catch(double) //捕獲並處理異常 }
【範例2】自定義異常型別
#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()
// 獲取錯誤碼
int geterrorid()
private:
// 錯誤碼
int m_errorid;
}; int main(int argc, char* argv)
else if ( throwerrorcode == 119 )
else if ( throwerrorcode == 120 )
else
} catch( myexcepction* pmyexcepction)
catch ( myexcepction myexcepction)
catch(...)
// 暫停
int temp;
std::cin >> temp;
return 0;
}異常的介面宣告
為了加強程式的可讀性,使函式的使用者能夠方便地知道所使用的函式會丟擲哪些異
常,可以在函式的宣告中列出這個函式可能丟擲的所有異常型別,例如:
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 異常處理
結構化異常 structured exception vs c 異常 c exception 大家都知道c 異常是c 語言的乙個特性,使用者可以使用throw的方式來丟擲異常,try catch 來捕獲異常。結構化異常是諸如,zero divided,access violations等異常,這些異...
c 異常處理
一 概述 c 自身有著非常強的糾錯能力,發展到如今,已經建立了比較完善的異常處理機制。c 的異常情況無非兩種,一種是語法錯誤,即程式中出現了錯誤的語句,函式,結構和類,致使編譯程式無法進行。另一種是執行時發生的錯誤,一般與演算法有關。關於語法錯誤,不必多說,寫 時心細一點就可以解決。c 編譯器的報錯...
C 異常處理
程式設計師常常忽視異常處理的重要性,這給他們自己的 造成相當大損害。本文將討論如何在c 中使用異常處理,並介紹在應用 中新增 片段以防止某些錯誤的一些簡單方法,這些錯誤可能導致程式異常終止。結構化異常處理 net框架提供一種標準的錯誤報告機制稱為結構化異常處理。這種機制依賴於應用中報告錯誤的異常。在...