C++异常详解
1.對異常的幾種處理方式
1)調(diào)用abort()
abort()函數(shù)的原型位于頭文件cstlib中,其實(shí)現(xiàn)是向標(biāo)準(zhǔn)錯(cuò)誤流發(fā)送abnormal program termination(程序異常終止),然后終止程序。
示例如下:
2)返回錯(cuò)誤碼
使用一個(gè)bool值來標(biāo)記,運(yùn)行結(jié)果是成功,還是失敗。
示例如下:
3)使用全局變量errno
出現(xiàn)異常時(shí)可以將全局變量errno設(shè)值,需要注意的是,要確保沒有其他的函數(shù)同時(shí)在使用這個(gè)全局變量
2.異常機(jī)制
涉及try,catch,throw關(guān)鍵字
示例代碼如下:
3.上面的示例中,我們拋出的是字符串,通常情況,我們會為每個(gè)可能出現(xiàn)的異常,定義一個(gè)異常類,當(dāng)出現(xiàn)異常時(shí),拋出該異常對象,catch塊對該異常對象進(jìn)行捕獲。
示例代碼如下:
4.異常規(guī)范
我們看下面的兩行代碼
double hmean(int x,int y) throw(bad_thing)//可能拋出bad_thing異常
double hmean(int x,int y) throw()//不拋出異常
其中后面的throw()部分就是異常規(guī)范,指出該函數(shù)可能拋出的異常。
程序員來確定可能拋出的異常,這樣并不好。
在C++11中,已經(jīng)摒棄了該規(guī)范。
5.棧解退
棧解退是很重要的概念。為什么這么說呢,當(dāng)拋出異常后,程序終止,或被catch塊捕捉,我們必須要考慮內(nèi)存的釋放問題。
我們先看一下,正常函數(shù)是如何處理內(nèi)存釋放的。
函數(shù)調(diào)用時(shí),調(diào)用函數(shù)的指令的地址會放到棧中,函數(shù)的參數(shù)或局部變量也將被添加到棧中或堆中。
如果在其中又調(diào)用了函數(shù),則執(zhí)行同樣的操作。
當(dāng)函數(shù)結(jié)束以后,程序會跳到被調(diào)用時(shí)存儲的地址處,棧頂?shù)脑乇会尫?#xff0c;同時(shí)釋放其自動變量。
如果自動變量時(shí)類對象,則類的析構(gòu)函數(shù)將被調(diào)用。
當(dāng)函數(shù)出現(xiàn)異常時(shí),程序也將不斷釋放棧,直到找到一個(gè)與該異常相對應(yīng)的try塊的返回地址。
隨后,控制權(quán)將轉(zhuǎn)到塊尾的catch處理程序,而不是函數(shù)調(diào)用后面的第一條語句,這個(gè)過程稱為棧解退。
和正常函數(shù)調(diào)用不同的是,函數(shù)返回將處理該函數(shù)放在棧中的對象,而函數(shù)異常則處理,try塊和throw之間放在棧中的對象。
有了棧解退機(jī)制,引發(fā)異常后,也會釋放調(diào)用中間函數(shù)時(shí)棧中的對象。
我們看看下面的兩個(gè)例子:
void test1() {string mesg("hello");if(false)throw exception();return; }void test2() {double *ar = new double[n];if(false)throw exception();delete [] ar;return; }對于test1,函數(shù)異常后,會進(jìn)行棧解退,string類析構(gòu)函數(shù)會被調(diào)用,占用的內(nèi)存將釋放。
對于test2,棧解退時(shí),將刪除棧中變量ar,但ar指向的內(nèi)存塊未釋放,并且不可訪問,會造成內(nèi)存泄漏的問題。此時(shí)要如何處理呢?
可以在引發(fā)異常的代碼塊中,捕獲該異常,釋放該內(nèi)存塊,然后重新引發(fā)異常。此時(shí),內(nèi)存塊就被釋放了。
6.關(guān)于catch塊
try {} catch(exception &ex) {}注意catch塊中參數(shù)為引用類型。當(dāng)throw異常向上拋出時(shí),該異常對象會被釋放,此時(shí)catch塊接收的異常對象為原始異常對象的一個(gè)副本。
使用引用的目的是,基類引用可以執(zhí)行派生類對象。若不使用引用,則只能調(diào)用基類的特性。
7.C++標(biāo)準(zhǔn)異常庫
標(biāo)準(zhǔn)異常類exception在頭文件exception中定義,類含有一個(gè)名為what()的虛擬成員函數(shù)。從exception派生的類可以重新定義它。
C++庫定義了很多基于exception的異常類型,此處不再詳細(xì)介紹。
?
參考資料:《C++ Primer.Plus》 pp.616-642
總結(jié)
- 上一篇: javascript常用判断写法
- 下一篇: s3c2440移植MQTT