c++学习笔记之异常
生活随笔
收集整理的這篇文章主要介紹了
c++学习笔记之异常
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1、異常
詳細見《c++異常分類》
基類exception有一個virtual函數(shù)what,返回錯誤信息(構(gòu)造函數(shù)設(shè)定的)。
基類exception的派生類有runtime_error(運行時錯誤,運行后檢測)、logic_error(邏輯錯誤,運行前檢測)和運算符拋出的異常。
運算符拋出的異常包括:bad_alloc(new拋出),bad_cast(dynamic_cast拋出),bad_typeid(typeid拋出),bad_exception
注意:
(1)如果一個函數(shù)拋出列表中包含bad_exception,那么如果一個意料之外的異常發(fā)生時,函數(shù)unexcpected將拋出bad_exception而不是結(jié)束程序,或調(diào)用set_unexpected指出的函數(shù)。
(2)自定義異??梢圆焕^承exception,所以catch(exception)不能保證捕獲所有異常
(3)catch(...)可以捕獲所有異常,但是由于沒有參數(shù)所以沒法查找該異常。
2、throw
除了拋出異常,也可以拋出表達式值或int值,如throw x > 5 或 throw 5
重新拋出異常如下:
catch(xxxx){
throw;
}
注意:在catch語句外有throw;語句會調(diào)用terminate函數(shù),會導致程序結(jié)束。
注意:帶有常見錯誤的函數(shù)應返回0或者NULL,而不是拋出異常。通過檢查返回值確定調(diào)用是否成功。
3、異常說明
列舉一系列函數(shù)可以拋出的異常,如:
void do(..) throw (ExceptionA, ExceptionB, ...){...}
注意:(1)拋出一個異常說明不允許的異常,會調(diào)用unexpected函數(shù)。
? ? ? ?? (2)沒有提供異常說明的函數(shù)可以拋出任何異常。在函數(shù)設(shè)置一個空異常說明throw()表示該函數(shù)沒有拋出任何異常,如果試圖拋出異常,調(diào)用unexpected函數(shù)。
4、處理意料之外異常
unexpected函數(shù)會調(diào)用函數(shù)set_unexpected注冊的函數(shù),如果沒有注冊會默認調(diào)用terminate函數(shù);
terminate函數(shù)會調(diào)用set_terminate注冊的函數(shù),如果沒有默認調(diào)用abort函數(shù)。
調(diào)用terminate函數(shù)的四種情況:
(1)對拋出的異常,異常機制找不到匹配的catch塊
(2)析構(gòu)函數(shù)試圖在堆棧展開時拋出一個異常
(3)在沒有異常要處理是試圖重新拋出異常(即第二條中的注意事項)
(4)調(diào)用函數(shù)unexpected將默認調(diào)用函數(shù)terminate
注意:set_unexpected和set_terminate會分別返回一個指向函數(shù)unexpected和terminate最后一次調(diào)用的函數(shù)的指針,如果第一次調(diào)用則返回0
注意:set_unexpected和set_terminate接收void返回值且沒有參數(shù)的函數(shù)指針作為參數(shù)。
注意:如果自定的終止函數(shù)的最后行為并不是退出程序,那么這個函數(shù)執(zhí)行完后會調(diào)abort終止程序。
5、堆棧展開
當一個異常被拋出但沒有在一個特定的域內(nèi)被捕獲時,該函數(shù)調(diào)用堆棧就會展開,并試圖在下一個外部try..catch內(nèi)捕獲。
展開 函數(shù)調(diào)用的堆棧,此函數(shù)中所有局部變量被銷毀。
6、構(gòu)造、析構(gòu)函數(shù)和異常
構(gòu)造函數(shù)可以拋出異常,異常拋出前會調(diào)用析構(gòu)函數(shù)。
如果由于堆棧展開而調(diào)用析構(gòu)函數(shù)拋出了一個異常,terminate函數(shù)被調(diào)用(terminate函數(shù)調(diào)用四個情況之一)。
7、處理new失敗
編譯器不同,處理方式不同,有三種:默認返回0;拋出異常(已包含頭文件<new>);默認拋出bad_alloc
set_new_handler可以注冊一個new失敗后的異常處理器。參數(shù)是一個沒有參數(shù)且返回值為空的函數(shù)的指針。
注意:一旦注冊在set_new_handler注冊了,那么new失敗時不會拋出bad_alloc,將錯誤堆棧推給new處理器來處理。
c++標準明確指出new處理器要完成以下任務(wù)的一個:
(1)釋放其他動態(tài)分配內(nèi)存,并返回運算符new來嘗試再次分配內(nèi)存
(2)拋出bad_alloc型異常
(3)調(diào)用函數(shù)abort或exit來結(jié)束程序
8、auto_ptr和動態(tài)分配內(nèi)存
如果一個異常發(fā)生在成功分配內(nèi)存后,delete語句前,那么發(fā)生內(nèi)存泄漏。auto_ptr可以處理這種情況。
一個auto_ptr對象維護了指向動態(tài)分配內(nèi)存的指針,當一個auto_ptr對象析構(gòu)函數(shù)被調(diào)用,它將對其指針的數(shù)據(jù)成員執(zhí)行delete。
由于auto_ptr類模板提供了重載運算符"*"和"->",auto_ptr對象可以作為一般指針變量使用。如:
auto_ptr<A> ptr(new A(...)); ptr->do(...) ? ? //do函數(shù)是A類的成員函數(shù)
注意: (1)auto_ptr不能指向數(shù)組和標準容器類。
? ? ? ? ? (2)auto_ptr能通過它的重載賦值運算符和拷貝構(gòu)造函數(shù)來傳遞動態(tài)內(nèi)存所有權(quán)
9、setjump和longjump
能夠指定從一個深度嵌套調(diào)用中立即跳轉(zhuǎn)到一個錯誤處理器(不必層層拋出)。但很危險,因為沒有調(diào)用為自動對象建立的析構(gòu)函數(shù)。
?
總結(jié)
以上是生活随笔為你收集整理的c++学习笔记之异常的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++学习笔记之输入/输出流
- 下一篇: 一步一步自定义spinner