C++程式丟擲異常後執行順序
1 解構函式中是否可以丟擲異常
首先我們看一個常見的問題,解構函式中是否可以丟擲異常。答案是C++標準指明解構函式不能、也不應該丟擲異常!
C++異常處理模型是為C++語言量身設計的,更進一步的說,它實際上也是為C++語言中物件導向而服務的。C++異常處理模型最大的特點和優勢就是對C++中的物件導向提供了最強大的無縫支援。那麼如果物件在執行期間出現了異常,C++異常處理模型有責任清除那些由於出現異常所導致的已經失效了的物件(也即物件超出了它原來的作用域),並釋放物件原來所分配的資源, 這就是呼叫這些物件的解構函式來完成釋放資源的任務,所以從這個意義上說,解構函式已經變成了異常處理的一部分。
下面我們來看看解構函式中不能丟擲異常的兩個理由:
1)如果解構函式丟擲異常,則異常點之後的程式不會執行,如果解構函式在異常點之後執行了某些必要的動作比如釋放某些資源,則這些動作不會執行,會造成諸如資源洩漏的問題。
2)通常異常發生時,c++的機制會呼叫已經構造物件的解構函式來釋放資源,此時若解構函式本身也丟擲異常,則前一個異常尚未處理,又有新的異常,會造成程式崩潰的問題。
那麼當無法保證在解構函式中不發生異常時, 該怎麼辦?
其實還是有很好辦法來解決的。那就是把異常完全封裝在解構函式內部,決不讓異常丟擲函式之外。這是一種非常簡單,也非常有效的方法。
//解構函式
~Class()
{
try{
}
catch(){ //這裡可以什麼都不做,只是保證catch塊的程式丟擲的異常不會被扔出解構函式之外。
}
}
2 程式丟擲異常後會怎樣
下面我們通過一個程式來觀察當程式中丟擲異常了是否會呼叫解構函式,異常丟擲中throw()後面的語句是否還會執行。程式如下,我們建立一個類,然後構造一個類物件,當丟擲異常我們看程式是否會進入解構函式以及throw()丟擲異常後面的程式:
#include<iostream>
using namespace std;
class setTry{
public:
setTry(){ //建構函式
cout << "start!" << endl; // 1
}
~setTry(){ //解構函式
cout << "end!" << endl; // 4
}
void dosomething(){
cout << "do something!" << endl; //類方法
}
};
int main(void)
{
setTry newOne;
try{
throw("error!"); //直接丟擲異常
newOne.dosomething();
}
catch (char* one){ //接收char*類異常
cout << one << endl; // 2
}
catch (...){ //接收其他型別異常
cout << "..." << endl;
}
cout << "return 0!"<<endl; // 3
return 0;
}
上面程式執行結就是按標註的1、2、3、4步驟輸出的,結果如下圖所示:
![這裡寫圖片描述](https://i.iter01.com/images/ddb059df428f8c3f81623a7a059965293875ce5edc86d1b4969fe274e4600089.png)
從執行結果就可以看出,丟擲異常try內部的throw()後面程式不會再執行,而try外部後面的程式會繼續執行。另外,解構函式在生存期結束也會被呼叫。
參考文獻:
http://blog.csdn.net/u012398613/article/details/17469581
相關文章
- java中異常丟擲後程式碼還會繼續執行嗎Java
- Swift 中 throws 異常丟擲Swift
- 啪,還敢丟擲異常
- oracle主動丟擲異常Oracle
- XCode除錯時丟擲異常,定位到某一行程式碼XCode除錯行程
- 擷取Spring框架自動丟擲異常Spring框架
- Java異常十一:使用throw丟擲異常物件;throw和throws的區別Java物件
- migrate:rollback 時 dropForeign 丟擲的異常解決方案
- Shiro身份驗證丟擲AuthenticationException異常,解決方案Exception
- 易優cms404頁面 丟擲HttpException異常HTTPException
- 高效Java:丟擲適合抽象的異常 - Kyle CarterJava抽象
- 程式碼安全測試第三十期:丟擲通用異常缺陷
- Redis client之Jedis線上程執行丟擲異常無法恢復的情形和解決方案Redisclient
- UNO 已知問題 在後臺執行緒觸發 SKXamlCanvas 的 Invalidate 且在 PaintSurface 事件丟擲異常將炸掉應用執行緒CanvasAI事件
- Sql執行順序SQL
- OpenCV 3.0後的 xfeatures2d 中detect()函式丟擲異常處理OpenCV函式
- Go包中程式碼執行順序Go
- 程式執行異常: Modulo by zero
- 中介軟體中丟擲異常,Handler中無法捕獲
- Golang 迴圈異常丟擲不影響整個請求Golang
- java類內部程式碼執行順序Java
- JavaScript執行順序分析JavaScript
- pipeline的執行順序
- mySQL 執行語句執行順序MySql
- Day42--異常向上丟擲
- C++輸出流cout的執行順序問題C++
- [譯] Ruby 2.6 Kernel 的system 方法增加是否丟擲異常引數。
- Laravel 8 表單驗證丟擲異常返回 json 格式資料LaravelJSON
- SQL語句執行順序SQL
- Select語句執行順序
- js執行順序Event LoopJSOOP
- Spring Aop的執行順序Spring
- sql mysql 執行順序 (4)MySql
- 如何修改監聽異常的優先順序
- SpringBoot中SpringSecurity 中不能丟擲異常UserNameNotFoundException 問題解析與處理Spring BootGseException
- 你是否真的懂 [程式的執行順序] 多程式 / 程式池
- JavaScript程式碼執行順序和資料型別JavaScript資料型別
- Pytest 順序執行,依賴執行,引數化執行
- async await、Promise、setTimeout執行順序AIPromise