C++異常機(jī)制概述

作者:melonstreet ?整理:cpp開發(fā)者 出處:https://www.cnblogs.com/QG-whz/
以下是正文
C++異常機(jī)制概述
一個最簡單的 try...catch... 的例子如下所示。我們有個程序用來記班級學(xué)生考試成績,考試成績分?jǐn)?shù)的范圍在 0-100 之間,不在此范圍內(nèi)視為數(shù)據(jù)異常:
int main(){int score=0;while (cin >> score){try{if (score > 100 || score < 0){throw score;}//將分?jǐn)?shù)寫入文件或進(jìn)行其他操作}catch (int score){cerr << "你輸入的分?jǐn)?shù)數(shù)值有問題,請重新輸入!";continue;}}}
throw 表達(dá)式;//示例代碼:throw包含在外層函數(shù)的try塊中void registerScore(int score){if (score > 100 || score < 0)throw score; //throw語句被包含在外層main的try語句塊中//將分?jǐn)?shù)寫入文件或進(jìn)行其他操作}int main(){int score=0;while (cin >> score){try{registerScore(score);}catch (int score){cerr << "你輸入的分?jǐn)?shù)數(shù)值有問題,請重新輸入!";continue;}}}

異常對象
| 標(biāo)準(zhǔn)異常類 | 描述 | 頭文件 |
|---|---|---|
| exception | 最通用的異常類,只報告異常的發(fā)生而不提供任何額外的信息 | exception |
| runtime_error | 只有在運(yùn)行時才能檢測出的錯誤 | stdexcept |
| rang_error | 運(yùn)行時錯誤:產(chǎn)生了超出有意義值域范圍的結(jié)果 | stdexcept |
| overflow_error | 運(yùn)行時錯誤:計算上溢 | stdexcept |
| underflow_error | 運(yùn)行時錯誤:計算下溢 | stdexcept |
| logic_error | 程序邏輯錯誤 | stdexcept |
| domain_error | 邏輯錯誤:參數(shù)對應(yīng)的結(jié)果值不存在 | stdexcept |
| invalid_argument | 邏輯錯誤:無效參數(shù) | stdexcept |
| length_error | 邏輯錯誤:試圖創(chuàng)建一個超出該類型最大長度的對象 | stdexcept |
| out_of_range | 邏輯錯誤:使用一個超出有效范圍的值 | stdexcept |
| bad_alloc | 內(nèi)存動態(tài)分配錯誤 | new |
| bad_cast | dynamic_cast類型轉(zhuǎn)換出錯 | type_info |
catch 關(guān)鍵字
允許從非常量到常量的類型轉(zhuǎn)換。
允許派生類到基類的類型轉(zhuǎn)換。
數(shù)組被轉(zhuǎn)換成指向數(shù)組(元素)類型的指針。
函數(shù)被轉(zhuǎn)換成指向函數(shù)類型的指針。
catch(type x){//做了一部分處理throw;}
棧展開、RAII
//一個沒有任何意義的類class A{public:A() :a(0){ cout << "A默認(rèn)構(gòu)造函數(shù)" << endl; }A(const A& rsh){ cout << "A復(fù)制構(gòu)造函數(shù)" << endl; }~A(){ cout << "A析構(gòu)函數(shù)" << endl; }private:int a;};int main(){try{A a ;throw a;}catch (A a){;}return 0;}
程序?qū)⑤敵觯?/p>

int main(){try{A * a= new A;throw *a;}catch (A a){;}getchar();return 0;}
程序運(yùn)行結(jié)果:

RAII機(jī)制有助于解決這個問題,RAII(Resource acquisition is initialization,資源獲取即初始化)。它的思想是以對象管理資源。為了更為方便、魯棒地釋放已獲取的資源,避免資源死鎖,一個辦法是把資源數(shù)據(jù)用對象封裝起來。程序發(fā)生異常,執(zhí)行棧展開時,封裝了資源的對象會被自動調(diào)用其析構(gòu)函數(shù)以釋放資源。C++ 中的智能指針便符合RAII。關(guān)于這個問題詳細(xì)可以看《Effective C++》條款13.
C++ 類構(gòu)造函數(shù)初始化列表的異常機(jī)制,稱為 function-try block。一般形式為:
myClass::myClass(type1 pa1)try: _myClass_val (初始化值){/*構(gòu)造函數(shù)的函數(shù)體 */}catch ( exception& err ){/* 構(gòu)造函數(shù)的異常處理部分 */};
若析構(gòu)函數(shù)拋出異常,調(diào)用 std::abort() 來終止程序。
在析構(gòu)函數(shù)中 catch 捕獲異常并作處理。
noexcept修飾符與noexcept操作符
void func() throw(int ,double ) {...}void func() throw(){...}
這是 throw 作為函數(shù)異常說明,前者表示 func()這個函數(shù)可能會拋出 int 或 double 類型的異常,后者表示 func() 函數(shù)不會拋出異常。事實(shí)上前者很少被使用,在 C++11 這種做法已經(jīng)被摒棄,而后者則被 C++11 的 noexcept 異常聲明所代替:
void func() noexcept {...}//等價于void func() throw(){...}
void func() noexcept(常量表達(dá)式);關(guān)于C++異常機(jī)制,歡迎在評論中和我探討。覺得文章不錯,請點(diǎn)贊和在看支持我繼續(xù)分享好文。謝謝!
評論
圖片
表情
