1. 程式人生 > >(30)try語句塊和異常處理

(30)try語句塊和異常處理

異常是指存在於執行時的反常行為,這些行為超出了函式正常功能的範圍。
當程式的某部分檢測到一個它無法處理的問題時,需要用到異常處理。異常處理機制為程式中異常檢測和異常處理這兩部分的協作提供支援。在C++語言中,異常處理包括:
一.throw表示式,異常檢測部分使用throw表示式來表示它遇到了無法處理的問題。我們說throw引發了異常。
二.try語句塊,異常處理部分使用try語句處理異常。try語句塊以關鍵字try開始,並以一個或多個catch子句結束,因catch子句處   理異常,所以他們被稱為異常處理程式碼。
三.一套異常類,用於在throw表示式和相關的catch子句之間傳遞異常的具體資訊

throw表示式

程式的異常檢測部分使用throw表示式引發一個異常。throw表示式包含關鍵字throw和緊跟其後的一個表示式,其中表達式的型別就
是丟擲的異常型別。throw表示式後面通常緊跟一個分號,從而構成一條表示式語句。
如:
if (i == 3) throw runtime_error("異常:i為3");

try語句塊

try語句塊的通用語法形式:
try{
   program-statement
}catch(exception-declaration){
   handler-statement
}catch(exception-declaration){
   handler-statement
} //.....
catch子句包括三部分:關鍵字ccatch、括號內一個(可能為命名的)物件的宣告(稱作異常宣告)以及一個塊。當選中了某個catch
子句處理處理異常了之後,執行與之對應的塊。catch一旦完成,程式跳轉到try語句快最後一個catch子句之後的那條語句繼續執行。
try語句塊內宣告的變數在塊外部無法訪問,特別是在catch子句內也無法訪問。
如:
int i = 1;	
while (cin >> i) {
	try {
	if (i == 3) throw runtime_error("異常:i為3");
	}
	catch (runtime_error e) {
	   cout << e.what() << endl;;
	}
}
cout << i << endl;  //輸入3時 輸出異常結果:異常:i為3
在複雜的系統中,程式在遇到丟擲異常的程式碼前,其執行路徑可能已經經過了多個try語句塊。例如,一個try語句可能呼叫了包含另一個try語句塊的函式,新的try語句塊可能呼叫了包含又一個try語句的新函式,以此類推。
  尋找處理程式碼的過程與函式呼叫鏈剛好相反。當異常被丟擲時,首先搜尋丟擲該異常的函式。如果沒有找到匹配的catch子句,終止該函式,並在呼叫該函式的函式中繼續尋找。如果還沒有找到匹配的catch子句,這個新的函式也被終止,繼續搜尋呼叫它的函式。以此類推,沿著程式的執行路徑逐層回退,直到找到適合型別的catch子句為止。
  如果最終還是沒能找到任何匹配的catch子句,程式轉到名為terminate的標準庫函式。該函式的行為與系統有關,一般情況下,執行該函式將導致程式非正常退出。
  對於那些沒有任何try語句塊定義的異常,也按照類似的方式處理:畢竟,沒有try語句塊也就意味著沒有匹配的catch子句。如果一段程式沒有try語句塊且發生了異常,系統會呼叫terminate函式並終止當前程式的執行。

標準異常

C++標準庫定義了一組類,用於報告標準庫函式遇到的問題。這些異常類也可以在使用者編寫的程式中使用,他們分別定義在4個頭檔案中:
一.exception標頭檔案定義了最通用的異常類exception。它們只報告異常的發生,不提供任何額外的資訊
二.stdexcept標頭檔案定義了幾種常用的異常類。
三.new標頭檔案定義了bad_alloc異常型別。
四.type_info標頭檔案定義了bad_cast異常型別

標準庫異常類只定義了幾種運算,包括建立或拷貝異常型別的物件,以及為異常型別的物件賦值。
  我們只能以預設初始化的方式初始化exception、bad_alloc和bad_cast物件,不允許為這些物件提供初始值。   
  其他異常型別的行為恰好相反:應該使用string物件或者C風格字串初始化這些型別的物件,但是不允許使用預設初始化的方式。當建立子類物件時,必須提供初始值,該初始值含有錯誤相關的資訊。
  異常型別只定義了一個名為waht的成員函式,該函式沒有任何引數,返回值是一個指向C風格字串的const char*。該字串的目的是提供關於異常的一些文字資訊。
  what函式返回的C風格字串的內容與異常物件的型別無關。如果異常型別有一個字串初始值,則what返回該字串。對於其他無初始值的異常型別來說,waht返回的內容由編譯器決定。