異常處理機制 本人節選自《21天學通C++》一書 轉載於broadview2006
C++並不是第一個對結構化運行期錯誤處理進行支持的語言。早在20世紀60年代,PL/1就提供了一種內建的異常處理機制;Ada也在20世紀80年代提供了自己的異常處理,而C++是在1989年時纔有了異常處理機制。但是,C++的異常處理是獨一無二的,並且其已經作爲了一種模型出現在一些新產生的語言之中。
提示:C++異常處理機制是一個用來有效地處理運行錯誤的非常強大且靈活的工具,它提供了更多的彈性、安全性和穩固性,克服了傳統方法所帶來的問題。
事實上,C++中的異常處理機制是一種把控制權從異常發生的地點轉移到一個匹配的處理函數或功能塊的機制。其中,異常可以是內建數據類型變量,也可以是對象。一般來說,異常處理機制包括4個部分。
try語句塊:即一個定義異常的語句塊。
catch語句塊:即一個或多個和try語句塊相關的處理,它們放在catch語句塊中。
throw表達式:即拋出異常語句。
異常本身。
一般來說,try語句塊包含可能拋出異常的代碼。例如,下列語句可能引發內存空間溢出的異常,其就包含在try語句中。
try
{
int * p = new int[1000000];
}
一個try語句塊後面將跟有一個或多個catch語句,其中,每一個catch語句可以處理不同類型的異常。例如:
try
{
int * p = new int[1000000];
//...
}
catch(std::bad_alloc& ) //內存空間不夠,分配內存失敗
{
}
catch (std::bad_cast&) //轉型失敗,分配內存失敗
{
}
catch語句塊僅僅被在try語句塊中的throw表達式及函數所調用。其中,throw表達式包括一個關鍵字throw及相關參數。例如:
try
{
throw 5;
}
catch(int n)
{
}
讀者需要注意的是,throw表達式和返回語句很相似。此外,throw語句可以沒有操作數,其格式如下所示:
throw;
注意:一般來說,如果目前沒有異常被處理,那麼執行一個沒有操作數的throw語句後,編譯系統將會調用terminate()函數結束程序。
當一個異常被拋出後,C++運行機制首先在當前的作用域尋找合適的處理catch語句塊。如果不存在這樣一個處理,那麼將會離開當前的作用域,進入更外圍的一層繼續尋找。這個過程不斷地進行下去直到合適的處理被找到爲止。此時堆棧已經被解開,並且所有的局部對象被銷燬。如果始終都沒有找到合適的處理,那麼程序將會終止。
【範例20-6】求一元二次方程的實根,要求加上異常處理,判斷b*b-4*a*c是否大於0,成立則求兩個實根,否則要求重新輸入,實現代碼如代碼清單20-6所示。
代碼清單20-6
1 #include <iostream>
2 #include <math.h> //包含頭文件
3 using namespace std; //使用命名空間
4 double sqrt_delta(double d) //定義函數
5 {
6 if(d < 0)
7 throw 1; //拋出異常
8 return sqrt(d); //返回平方根值
9 }
10 double delta(double a, double b, double c) //定義函數
11 {
12 double d = b * b - 4 * a * c;
13 return sqrt_delta(d); //調用sqrt_delta()函數
14 }
15 void main()
16 {
17 double a, b, c;
18 cout << "please input a, b, c" << endl;
19 cin >> a >> b >> c; //接收輸入
20 while(true) //循環
21 {
22 try //定義異常
23 {
24 double d = delta(a, b, c); //調用函數
25 cout << "x1: " << (d - b) / (2 * a);
26 cout << endl;
27 cout << "x2: " << -(b + d) / (2 * a);
28 cout << endl;
29 break; //跳出循環
30 }
31 catch(int) //定義異常處理
32 {
33 cout << "delta < 0, please reenter a, b, c.";
//重新輸入係數
34 cin >> a >> b >> c;
35 }
36 }
37 }
【運行結果】在Visual C++中新建一個【C++ Source File】文件,輸入上述的代碼,編譯無誤後運行。
【範例解析】上述範例實現了對於用戶輸入的一元二次方程係數的判斷,由於只有方程的係數符合b*b-4*a*c>0的條件時纔有實根,所以上述代碼中的sqrt_delta ()函數中包含了異常定義。在上述代碼的第31~35行中的catch語句塊中包含了對該異常的處理。
提示:catch語句後的參數(即數據類型)需要與throw語句後的表達式數據類型相同。如上述代碼中第7行throw語句後的表達式爲1,
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/broadview2006/archive/2009/01/15/3772488.aspx