c++中,當異常遇見構造與析構

c++中,當異常遇見構造與析構,會碰撞出什麼樣的火花?

本來應該說,當構造與析構遇見異常的,但是好像念起來不太順。就改了下。哈哈。

我們知道資源是有限的,申請資源和釋放資源是要配對執行的。有申請無釋放,就會造成資源泄露。
廢話不多說,先上代碼,如下是一個正常的簡單代碼。先了解一下,之後再進行改造分析。
B類中有一個A類的對象指針。聲明下:這個例子中的資源,就是B類中A類指針所指向的內存。
代碼的運行結果如下:

1. 構造函數拋異常
1.1. 在B的構造中加異常——未申請資源時拋異常。
執行結果如下:
可以看出,B類構造未完成,但是也沒有申請資源,所以並未出現內存泄露。

1.2 在B的構造中加異常——申請資源後拋異常。
執行結果如下:
可以看出,B類構造開始,在A構造完成後,拋也異常,併成功捕獲。
但是:此時並沒有調用B類的析構函數,也就沒有析構已經構造好的A對象,造成構造析構不一致,內存泄露!!!
結論:
1. 構造函數是可以拋異常的。
2. 構造函數中,如果有申請資源,那麼在申請資源後拋異常,而沒有在構造函數內部進行捕獲異常並釋放資源,就會造成資源泄露。如上面的內存泄露。
3. 個人理解,構造函數中如果有申請資源的動作,一定不要輕易拋出異常,最好在內部進行異常消化。
不讓內部的異常拋外面去。
上面只是以最簡單的方式說明,如果完善,可以處理具體異常類型,也可以加RAII機制,如scope_guard之類的處理。

2. 析構函數拋異常
看運行結果,直接就拋外面來了,core掉了!!!捕獲異常都沒捕獲住!!!
查看下core文件,函數調用棧如下:
那就沒什麼好講的了,c++的異常處理機制導致的。具體細節邏輯,這裏不闡述。
結論:
2 析構函數中產生的異常,拋出後,在析構函數外無法捕獲,程序會直接崩潰!
2 定義析構函數時,裏面的異常不能往外拋,應該在析構函數中捕獲並正確處理。注意這裏說的是捕獲並正確處理,不是說捕獲後就不管了,不管那叫掩蓋錯誤,程序運行下去甚至會有比崩潰更嚴重的後果。
如下結果運行正常!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章