異常

try語句塊

try{
	program-statements
} catch(exception-declaration) {
	handler-statements
} catch(exception-declaration) {
	handler-statements
}// ...

 

異常(exception)

當拋出一個異常時,程序會暫停當前函數的執行過程並開始尋找與異常相匹配的catch子句。當throw出如今一個try block時,檢查與該try塊關聯的catch子句。若是找到。則進行處理。若是沒找到,則繼續檢查與外層try匹配的catch子句。一直這樣展開。直到找到爲止。或者退出主函數而後查找過程終止。這個過程稱爲 棧展開(stack unwinding)函數

在處理異常的過程當中有個問題必須注意優化

棧展開過程當中對象被自動銷燬

在發生異常時,好比發生在構造函數中,可能有些成員已經初始化完了。有些成員還未初始化。則已構造的的成員,咱們也要確保其能被正確地銷燬。this

在發生異常的函數中,析構函數老是會被執行,可是函數中釋放資源的代碼卻可能被調用。(這是一個特性吧)spa

若是在析構函數中出現了異常。則可能致使該類異常退出。因此在析構函數中不該該拋出其不能處理的異常。若是確實要執行可能致使異常的操做,則該操做應該放在try語句塊當中。指針

下面這個例子。在發生異常後,則v和in都會被自動釋放掉。由於他們都有對應的析構函數,p指針也會被銷燬。可是指針指向的部分不會被銷燬。這部分只有new沒有對應的析構函數。因此會形成內存泄漏。code

void exercise(int *b, int *e)
{
	vector<int> v(b,e);
	int* p = new int[v.size()];
	ifstream in("this");
	//此處發生異常


}

 

在catch語句裏若是不是使用解引用符,或者指針。則會拷貝一個異常的副本。對象

catch(...) //捕獲全部的異常
throw;//在處理異常的代碼以外遇到了該語句。編譯器會調用terminate

noexcept異常說明符,也是運算符

該說明符會聲明函數不會拋出異常。內存

void fun(int) noexcept; //不會拋出異常。若是拋出了異常。
//則程序就會調用terminate以確保程序遵照不拋出異常的承諾。
void alloc(int);//可能拋出異常。

好處就是編譯器確認函數不會拋出異常,則它就能夠對這些代碼作特殊的優化。這些優化操做不適用於可能出錯的代碼。ci

noexcept是一個一元運算符。用於判斷給定的表達式是否會拋出異常。資源

noexcept(g());//若是函數g不會拋出異常。
//即g()調用的全部函數都聲明爲不拋出異常,且自己不含有throw語句,則爲true。
//或者爲false
相關文章
相關標籤/搜索