C++ 高级篇(三)—— 出错处理
本節介紹的出錯處理是ANSI-C++ 標準引入的新功能。如果你使用的C++ 編譯器不兼容這個標準,則你可能無法使用這些功能。
在編程過程中,很多時候我們是無法確定一段代碼是否總是能夠正常工作的,或者因為程序訪問了并不存在的資源,或者由于一些變量超出了預期的范圍,等等。
這些情況我們統稱為出錯(例外),C++ 新近引入的三種操作符能夠幫助我們處理這些出錯情況: try, throw 和 catch 。
它們的一般用法是:
try {// code to be triedthrow exception;}catch (type exception){// code to be executed in case of exception}它們所進行的操作是:
- try 語句塊中的代碼被正常執行。如果有例外發生,代碼必須使用關鍵字throw 和一個參數來扔出一個例外。這個參數可以是任何有效的數據類型,它的類型反映了例外的特征。
- 如果有例外發生,也就是說在try 語句塊中有一個throw 指令被執行了,則catch 語句塊會被執行,用來接收throw傳來的例外參數。
例如:
| // exceptions#include <iostream.h>int main () {char myarray[10];try {for (int n=0; n<=10; n++) {if (n>9) throw "Out of range";myarray[n]='z';}} catch (char * str) {cout << "Exception: " << str << endl;}return 0;} | Exception: Out of range |
在這個例子中,如果在n 循環中,n 變的大于9 了,則仍出一個例外,因為數組 myarray[n] 在這種情況下會指向一個無效的內存地址。當throw 被執行的時候,try 語句塊立即被停止執行,在try 語句塊中生成的所有對象會被銷毀。此后,控制權被傳遞給相應的catch 語句塊(上面的例子中即執行僅有的一個catch)。最后程序緊跟著catch 語句塊繼續向下執行,在上面的例子中就是執行 return 0;.
throw 語法與 return 相似,只是參數不需要擴在括號。
catch 語句塊必須緊跟著try 語句塊后面,中間不能有其它的代碼。catch 捕獲的參數可以是任何有效的數據類型。catch 甚至可以被重載以便能夠接受不同類型的參數。在這種情況下被執行catch 語句塊是相應的符合被throw扔出的參數類型的那一個:
| // exceptions: multiple catch blocks#include <iostream.h>int main () {try {char * mystring;mystring = new char [10];if (mystring == NULL) throw "Allocation failure";for (int n=0; n<=100; n++) {if (n>9) throw n;mystring[n]='z';}} catch (int i) {cout << "Exception: ";cout << "index " << i << " is out of range" << endl;} catch (char * str) {cout << "Exception: " << str << endl;}return 0;} | Exception: index 10 is out of range |
在上面的例子中,有兩種不同的例外可能發生:
我們還可以定義一個catch 語句塊來捕獲所有的例外,不論扔出的是什么類型的參數。這種情況我們需要在catch 或面的括號中寫三個點來代替原來的參數類型和名稱,如:
try {// code here}catch (...) {cout << "Exception occurred";}try-catch 也是可以被嵌套使用的。在這種情況下,我們可以使用表達式throw;(不帶參數)將里面的catch 語句塊捕獲的例外傳遞到外面一層,例如:
try {try {// code here}catch (int n) {throw;}}catch (...) {cout << "Exception occurred";}沒有捕獲的例外 (Exceptions not caught)
如果由于沒有對應的類型,一個例外沒有被任何catch 語句捕獲,特殊函數terminate 將被調用。
這個函數通常已被定義了,以便立即結束當前的進程(process),并顯示一個“非正常結束”( "Abnormal termination")的出錯信息。它的格式是:
void terminate(); ?標準例外 (Standard exceptions)
一些C++ 標準語言庫中的函數也會扔出一些列外,我們可以用try 語句來捕獲它們。這些例外扔出的參數都是std::exception 引申出的子類類型的。這個類(std::exception) 被定義在C++ 標準頭文件?中,用來作為exceptions標準結構的模型:
因為這是一個類結構,如果你包括了一個catch 語句塊使用地址(reference)來捕獲這個結構中的任意一種列外 (也就是說在類型后面加地址符 &),你同時可以捕獲所有引申類的例外 (C++的繼承原則)。
下面的例子中,一個類型為 bad_typeid 的例外(exception的引申類),在要求類型信息的對象為一個空指針的時候被捕獲:
| // standard exceptions#include <iostream.h>#include <exception>#include <typeinfo>class A {virtual void f() {}; };int main () {try {A * a = NULL;typeid (*a);} catch (std::exception& e) {cout << "Exception: " << e.what();}return 0;} | Exception: Attempted typeid of NULL pointer |
本節介紹的出錯處理是ANSI-C++ 標準引入的新功能。如果你使用的C++ 編譯器不兼容這個標準,則你可能無法使用這些功能。
在編程過程中,很多時候我們是無法確定一段代碼是否總是能夠正常工作的,或者因為程序訪問了并不存在的資源,或者由于一些變量超出了預期的范圍,等等。
這些情況我們統稱為出錯(例外),C++ 新近引入的三種操作符能夠幫助我們處理這些出錯情況: try, throw 和 catch 。
它們的一般用法是:
try {// code to be triedthrow exception;}catch (type exception){// code to be executed in case of exception}它們所進行的操作是:
- try 語句塊中的代碼被正常執行。如果有例外發生,代碼必須使用關鍵字throw 和一個參數來扔出一個例外。這個參數可以是任何有效的數據類型,它的類型反映了例外的特征。
- 如果有例外發生,也就是說在try 語句塊中有一個throw 指令被執行了,則catch 語句塊會被執行,用來接收throw傳來的例外參數。
例如:
| // exceptions#include <iostream.h>int main () {char myarray[10];try {for (int n=0; n<=10; n++) {if (n>9) throw "Out of range";myarray[n]='z';}} catch (char * str) {cout << "Exception: " << str << endl;}return 0;} | Exception: Out of range |
在這個例子中,如果在n 循環中,n 變的大于9 了,則仍出一個例外,因為數組 myarray[n] 在這種情況下會指向一個無效的內存地址。當throw 被執行的時候,try 語句塊立即被停止執行,在try 語句塊中生成的所有對象會被銷毀。此后,控制權被傳遞給相應的catch 語句塊(上面的例子中即執行僅有的一個catch)。最后程序緊跟著catch 語句塊繼續向下執行,在上面的例子中就是執行 return 0;.
throw 語法與 return 相似,只是參數不需要擴在括號。
catch 語句塊必須緊跟著try 語句塊后面,中間不能有其它的代碼。catch 捕獲的參數可以是任何有效的數據類型。catch 甚至可以被重載以便能夠接受不同類型的參數。在這種情況下被執行catch 語句塊是相應的符合被throw扔出的參數類型的那一個:
| // exceptions: multiple catch blocks#include <iostream.h>int main () {try {char * mystring;mystring = new char [10];if (mystring == NULL) throw "Allocation failure";for (int n=0; n<=100; n++) {if (n>9) throw n;mystring[n]='z';}} catch (int i) {cout << "Exception: ";cout << "index " << i << " is out of range" << endl;} catch (char * str) {cout << "Exception: " << str << endl;}return 0;} | Exception: index 10 is out of range |
在上面的例子中,有兩種不同的例外可能發生:
我們還可以定義一個catch 語句塊來捕獲所有的例外,不論扔出的是什么類型的參數。這種情況我們需要在catch 或面的括號中寫三個點來代替原來的參數類型和名稱,如:
try {// code here}catch (...) {cout << "Exception occurred";}try-catch 也是可以被嵌套使用的。在這種情況下,我們可以使用表達式throw;(不帶參數)將里面的catch 語句塊捕獲的例外傳遞到外面一層,例如:
try {try {// code here}catch (int n) {throw;}}catch (...) {cout << "Exception occurred";}沒有捕獲的例外 (Exceptions not caught)
如果由于沒有對應的類型,一個例外沒有被任何catch 語句捕獲,特殊函數terminate 將被調用。
這個函數通常已被定義了,以便立即結束當前的進程(process),并顯示一個“非正常結束”( "Abnormal termination")的出錯信息。它的格式是:
void terminate();?標準例外 (Standard exceptions)
一些C++ 標準語言庫中的函數也會扔出一些列外,我們可以用try 語句來捕獲它們。這些例外扔出的參數都是std::exception 引申出的子類類型的。這個類(std::exception) 被定義在C++ 標準頭文件?中,用來作為exceptions標準結構的模型:
因為這是一個類結構,如果你包括了一個catch 語句塊使用地址(reference)來捕獲這個結構中的任意一種列外 (也就是說在類型后面加地址符 &),你同時可以捕獲所有引申類的例外 (C++的繼承原則)。
下面的例子中,一個類型為 bad_typeid 的例外(exception的引申類),在要求類型信息的對象為一個空指針的時候被捕獲:
| // standard exceptions#include <iostream.h>#include <exception>#include <typeinfo>class A {virtual void f() {}; };int main () {try {A * a = NULL;typeid (*a);} catch (std::exception& e) {cout << "Exception: " << e.what();}return 0;} | Exception: Attempted typeid of NULL pointer |
總結
以上是生活随笔為你收集整理的C++ 高级篇(三)—— 出错处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++隐式类型转换存在的陷阱
- 下一篇: 微信话术自动回复机器人软件