爲什麼析構函數中不能拋出異常?

1、C++標準指明析構函數不能、也不應該拋出異常

C++異常處理模型是爲C++語言量身設計的,更進一步的說,它實際上也是爲C++語言中面向對象而服務的。C++異常處理模型最大的特點和優勢就是對C++中的面向對象提供了最強大的無縫支持。那麼如果對象在運行期間出現了異常,C++異常處理模型有責任清除那些由於出現異常所導致的已經失效了的對象(也即對象超出了它原來的作用域),並釋放對象原來所分配的資源,這就是調用這些對象的析構函數來完成釋放資源的任務,所以從這個意義上說,析構函數已經變成了異常處理的一部分。

上面的論述C++異常處理模型它其實是有一個前提假設——析構函數中是不應該再有異常拋出的。

2、《More Effective c++》提出析構函數不能拋出異常的兩點理由

1)如果析構函數拋出異常,則異常點之後的程序不會執行,如果析構函數在異常點之後執行了某些必要的動作比如釋放某些資源,則這些動作不會執行,會造成諸如資源泄漏的問題。

2)通常異常發生時,c++的機制會調用已經構造對象的析構函數來釋放資源,此時若析構函數本身也拋出異常,則前一個異常尚未處理,又有新的異常,會造成程序崩潰的問題。

3、當無法保證在析構函數中不發生異常時, 該怎麼辦?

解決方式就是把異常完全封裝在析構函數內部,決不讓異常拋出函數之外。這是一種非常簡單,也非常有效的方法。

~ClassName()
{
  try
  {
      	do_something();
  }
  catch()
  {  
  //這裏可以什麼都不做,只是保證catch塊的程序拋出的異常不會被扔出析構函數之外。
   }
}

4、總結

析構函數中不能拋出異常的原因:

(1) 影響資源釋放等預定義的動作
(2) 引發更多的異常,導致程序崩潰
(3) 析構函數本身如果作爲異常處理的一部分操作,不應該再拋出異常

轉載自:析構函數不能拋出異常

謝謝閱讀

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