1,C++ 內置了異常處理的語法元素 try ... catch ...;
1,try 語句處理正常代碼邏輯;
2,catch 語句處理異常情況;
3,try 語句中的異常由對應的 catch 語句處理;
1,代碼示例:
1 try 2 { 3 double r = divide(1, 0); // divide() 函數里面產生除 0 異常,於是 divide() 函數就會將這個異常拋出到調用的地點,這個地點正好在 try 語句塊中,其會將捕捉到的異常扔給下面的 catch 代碼塊,catch 代碼塊就可以將除 0 異常捕捉到,於是打印 Divided by zero ...; 4 } 5 catch(...) 6 { 7 cout << "Divided by zero ..." << endl; 8 }
2,C++ 通過 throw 語句拋出異常信息:
1,代碼示例:
1 double divide(double a, double b) 2 { 3 const double delta = 0.000000001; 4 double ret = 0; 5 6 if( !((-delta < b) && (b < delta)) ) 7 { 8 ret = a / b; 9 } 10 else 11 { 12 throw 0; // 0 這個字面值常量代表當前的異常元素,表示產生除 0 異常; 異常元素可以是一個值、一個對象、一個字符串等; 扔出異常元素后,divide() 就會立即返回到調用點; 13 } 14 15 return ret; 16 }
2,C++ 中 throw 這個新的關鍵字就是用來仍出異常元素的,我們簡稱為“異常”,每一個異常都需要被 catch 語句來處理;
3,C++ 異常處理分析:
1,throw 拋出的異常必須被 catch 處理:
1,當前函數能夠處理異常,程序往下執行;
2,當前函數無法處理異常,則函數停止執行,並返回;
1,返回是異常返回,和正常返回不一樣;
2,異常產生后的函數返回是沒有返回值的;
2,未被處理的異常會順着函數調用棧向上傳播,知道被處理為止,否則程序將停止執行;
3,C++ 異常處理初探編程實驗:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 double divide(double a, double b) 7 { 8 const double delta = 0.000000000000001; 9 double ret = 0; 10 11 if( !((-delta < b) && (b < delta)) ) 12 { 13 ret = a / b; 14 } 15 else 16 { 17 throw 0; 18 } 19 20 return ret; 21 } 22 23 int main(int argc, char *argv[]) 24 { 25 try 26 { 27 double r = divide(1, 0); // 扔出異常后,divide() 自身沒有 try...catch...,不能處理異常,所以 divide() 這個函數就會立即的停止並且帶着異常元素返回到調用點,而 main() 函數中當也沒有try...catch... 語句時,異常向上傳播,main() 已經是第一個函數了,則導致整個程序異常停止,編譯器顯示:terminate called after throwing an instance of 'int',已放棄;當 main() 中包含 try...catch... 語句時,程序正常打印:Divided by zero...; 28 29 cout << "r = " << r << endl; 30 } 31 catch(...) // “...” 表示見下分析; 32 { 33 cout << "Divided by zero..." << endl; 34 } 35 36 return 0; 37 }
4,同一個 try 語句可以跟上多個 catch 語句:
1,catch 語句可以定義具體處理的異常類型;
2,不同類型的異常由不同的 catch 語句負責處理;
3,try 語句中可以拋出任何類型的異常;
1,try 語句塊用於放置可能產生異常的代碼,工程里面一般都習慣將正常功能邏輯代碼放在 try 語句塊中,然后后面跟上多個 catch 語句;
2,可以是一個 int、字符串、對象;
4,catch(...) 用於處理所有類型的異常;
1,一般情況作為最后出場的語句塊;
5,任何異常都只能被捕獲(catch)一次;
1,只要被 catch 一次,其它的 catch 就沒有捕獲機會了;
5,異常處理的匹配規則:
1,示意圖:
2,try 語句塊中直接通過 throw 扔出整型異常;
3,扔出后發現是在 catch 語句塊中,然后這個異常就會進行 catch 語句塊的匹配;
4,從上向下嚴格匹配每個 catch 它所需要捕獲的異常類型;
5,匹配 catch 語句塊所標識的類型時,是不會進行任何的類型轉換的;
6,如果說不能夠嚴格匹配上,那么當前的異常沒有被捕獲,當前的函數就會立即的停止執行,並且帶着這個異常沿着函數調用棧順序的返回;
6,異常類型匹配編程實驗:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 void Demo1() 7 { 8 try 9 { 10 throw 'c'; 11 } 12 catch(char c) 13 { 14 cout << "catch(char c)" << endl; 15 } 16 catch(short c) 17 { 18 cout << "catch(short c)" << endl; 19 } 20 catch(double c) 21 { 22 cout << "catch(double c)" << endl; 23 } 24 catch(...) // 當把它放到其它 catch 語句塊前面的時候,編譯器顯示:error: '...' handler must be the last handler for its try block; 25 { 26 cout << "catch(...)" << endl; 27 } 28 } 29 30 void Demo2() 31 { 32 throw "D.T.Software; // 兩個分開執行的; 33 throw string("D.T.Software"); 34 } 35 36 int main(int argc, char *argv[]) 37 { 38 Demo1(); 39 40 try 41 { 42 Demo2(); // 認為它可能產生字符串異常,所以將它放到了這里; 43 } 44 catch(char* s) 45 { 46 cout << "catch(char *s)" << endl; 47 } 48 catch(const char* cs) // 沒有這個 catch 語句塊時,第一個異常執行后編譯器顯示:terminate called after throwing an instance of 'char const *'; 49 { 50 cout << "catch(const char *cs)" << endl; 51 } 52 catch(string ss) 53 { 54 cout << "catch(string ss)" << endl; 55 } 56 57 return 0; 58 }
7,小結:
1,C++ 中直接支持異常處理的概念;
2,try ... catch ... 是 C++ 中異常處理的專用語句;
3,try 語句處理正常代碼邏輯,catch 語句處理異常情況;
4,同一個 try 語句可以跟上多個 catch 語句;
5,異常處理必須嚴格匹配,不進行任何的類型轉換;