您好,登錄后才能下訂單哦!
這篇文章運用簡單易懂的例子給大家介紹C++中怎樣處理異常捕捉,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
前言
在閱讀別人開發的項目中,也許你會經常看到了多處使用異常的代碼,也許你也很少遇見使用異常處理的代碼。那在什么時候該使用異常,又在什么時候不該使用異常呢?在學習完異常基本概念和語法之后,后面會有講解。
(1)異常拋出和捕捉語句
//1.拋出異常 throw 異常對象 //2.異常捕捉 try{ 可能會發生異常的代碼 }catch(異常對象){ 異常處理代碼 }
(2)異常的處理規則
(3)實例
實例1:拋出自定義類型異常。
class Data { public: Data() {} }; void fun(int n) { if(n==0) throw 0;//拋異常 int異常 if(n==1) throw "error"; //拋字符串異常 if(n==2) { Data data; throw data; } if(n>3) { throw 1.0; } } int main() { try { fun(6);//當異常發生fun里面,fun以下代碼就不會再執行,調到catch處執行異常處理代碼,后繼續執行catch以外的代碼。當throw拋出異常后,沒有catch捕捉,則整個程序會退出,不會執行整個程序的以下代碼 cout<<"*************"<<endl; }catch (int i) { cout<<i<<endl; }catch (const char *ptr) { cout<<ptr<<endl; }catch(Data &d) { cout<<"data"<<endl; }catch(...)//抓取 前面異常以外的所有其他異常 { cout<<"all"<<endl; } return 0; }
實例2:標準出錯類拋出和捕捉異常。
#include <iostream> using namespace std; int main() { try { char* p = new char[0x7fffffff]; //拋出異常 } catch (exception &e){ cout << e.what() << endl; //捕獲異常,然后程序結束 } return 0; }
輸出結果:
當使用new進行開空間時,申請內存失敗,系統就會拋出異常,不用用戶自定義異常類型,此時捕獲到異常時,就可告訴使用者是哪里的錯誤,便于修改。
實例3:繼承標準出錯類的派生類的異常拋出和捕捉。
#include <iostream> #include <exception> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> using namespace std; class FileException :public exception { public: FileException(string msg) { this->exStr = msg; } virtual const char*what() const noexcept//聲明這個函數不能再拋異常 { return this->exStr.c_str(); } protected: string exStr; }; void fun() { int fd = ::open("./open.txt",O_RDWR); if(fd<0) { FileException openFail("open fail"); //創建異常對象 throw openFail;//拋異常 } } int main( ) { try { fun(); } catch (exception &e) {//一般需要使用引用 cout<<e.what()<<endl; } cout<<"end"<<endl; return 0; }
當文件不存在時,輸出結果:
如果在Linux上運行,上述代碼需要根據環境修改:
98標準寫法
~FileException()throw(){}//必須要 virtual const char*what() const throw()//聲明這個函數不能再拋異常 { return this->exStr.c_str(); } //編譯 g++ main.cpp
2011標準寫法
~FileException()noexcept{}//必須要 virtual const char*what() const noexcept//聲明這個函數不能再拋異常 { return this->exStr.c_str(); } //編譯 g++ main.cpp -std=c++11 指定用c++11標準編譯
(4)總結
1. 使用異常處理的優點:
傳統錯誤處理技術,檢查到一個錯誤,只會返回退出碼或者終止程序等等,我們只知道有錯誤,但不能更清楚知道是哪種錯誤。使用異常,把錯誤和處理分開來,由庫函數拋出異常,由調用者捕獲這個異常,調用者就可以知道程序函數庫調用出現的錯誤是什么錯誤,并去處理,而是否終止程序就把握在調用者手里了。
2. 使用異常的缺點:
如果使用異常,光憑查看代碼是很難評估程序的控制流:函數返回點可能在你意料之外,這就導致了代碼管理和調試的困難。啟動異常使得生成的二進制文件體積變大,延長了編譯時間,還可能會增加地址空間的壓力。
C++沒有垃圾回收機制,資源需要自己管理。有了異常非常容易導致內存泄漏、死鎖等異常安全問題。 這個需要使用RAII來處理資源的管理問題。學習成本較高。
C++標準庫的異常體系定義得不好,導致大家各自定義各自的異常體系,非常的混亂。
3. 什么時候使用異常?
建議:除非已有的項目或底層庫中使用了異常,要不然盡量不要使用異常,雖然提供了方便,但是開銷也大。
4. 程序所有的異常都可以catch到嗎?
并非如此,只有發生異常,并且又拋出異常的情況才能被catch到。例如,數組下標訪問越界的情況,系統是不會自身拋出異常的,所以我們無論怎么catch都是無效的;在這種情況,我們需要自定義拋出類型,判斷數組下標是否越界,然后再根據自身需要throw自定義異常對象,這樣才可以catch到異常,并進行進一步處理。
關于C++中怎樣處理異常捕捉就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。