異常是指存在於運行時的反常行為,這些行為超出了函數正常功能的范圍。典型的異常包括失去數據庫連接以及遇到意外輸入等。處理反常行為可能是設計所有系統最難的一部分。
如果程序中含有可能引發異常的代碼,那么通常也會有專門的代碼處理問題。例如,如果程序的問題是輸入無效,則異常處理部分可能會要求用戶重新輸入正確的數據;如果丟失了數據庫連接,會發出報警信息。
異常處理機制為程序中異常檢測和異常處理這兩部分的協作提供支持。在C++語言中,異常處理包括:
●throw表達式。異常檢測。
●try語句塊。異常處理。
●一套異常類,用於在throw表達式和相關的catch子句之間傳遞異常的具體信息。
throw表達式
程序的異常檢測部分使用throw表達式引發一個異常。throw表達式包含關鍵字throw和緊隨其后的一個表達式,其中表達式的類型就是拋出的異常類型。throw表達式后面緊跟一個分號,從而構成一條表達式語句。
throw runtime_error("Data must refer to ...");
拋出的異常是類型runtime_error的對象。拋出異常將終止當前的函數,並把控制權轉移給能處理該異常的代碼。
try語句塊
try{
program-statements
}catch(exception-declaration){
handler-statments
}catch(exception-declaration){
handler-statements
}//...
一如往常,try語句塊內聲明的變量在塊外部無法訪問,特別是在catch子句內也無法訪問。
函數在尋找處理代碼的過程中退出
一個try語句塊可能調用了包含另一個try語句塊的函數,新的try語句塊可能調用了包含又一個try語句塊的新函數,以此類推。
尋找處理代碼的過程與函數調用鏈剛好相反。當異常被拋出時,首先搜索拋出該異常的函數。如果沒有找到匹配的catch子句,終止該函數,並在調用該函數的函數中繼續尋找。以此類推,沿着程序的執行路徑逐層回退,直到找到適當類型的catch子句為止。
如果最終還是沒能找到任何匹配的catch子句,程序轉到名為terminate的標准庫函數。該函數的行為與系統有關,一般情況下,執行該函數將導致程序非正常退出。
如果一段程序沒有try語句塊且發生了異常,系統會調用terminate函數並終止當前程序的執行。
note:編寫異常安全的代碼非常困難
異常中斷了程序的正常流程。
對於一些程序來說,當異常發生時只是簡單地終止程序。
但是對於那些要處理異常並繼續執行的程序,就要加倍注意了。我們必須時刻清楚異常何時發生,異常發生后程序應如何確保對象有效、資源無泄漏、程序處於合理狀態,等等。
標准異常
c++標准庫定義了一組類,用於報告標准庫函數遇到的問題。這些異常類也可以在用戶編寫的程序中使用,它們分別定義在4個頭文件中:
exception
st
dexcept
new
type_info
標准庫異常類只定義了幾種運算,包括創建或拷貝異常類型的對象,以及為異常類型的對象賦值。
應該使用string對象或者C風格字符串初始化這些類型的對象,但是不允許使用默認初始化的方式。當創建此類對象時,必須提供初始值,該初始值含有錯誤相關的信息。除了exception、bad_alloc和bad_cast對象,不允許為這些對象提供初始值。
<stdexcept>定義的異常類
exception最常見的問題
runtime_error只有在運行時才能檢測出的問題
range_error運行時的錯誤:生成的結果超出了有意義的值域范圍
overflow_error運行時錯誤:計算上溢
underflow_error運行時錯誤:計算下溢
logic_error程序邏輯錯誤
domain_error邏輯錯誤:參數對應的結果值不存在
invalid_argument 邏輯錯誤:無效參數
length_error邏輯錯誤:試圖創建一個超出該類型最大長度的對象
out_of_range邏輯錯誤:使用一個超出有效范圍的值