異常與建構函式、解構函式

來源:互聯網
上載者:User
文章目錄
  • 絕對不要將異常拋出解構函式

C++代碼,發現異常沒那麼簡單,使用須謹慎。

翻閱了《Effective C++》 《More Effective C++》《Inside The C++ Object Model》的相關章節,大概弄明白了一些東東,總結在本文。 

本文不是總結普適的C++異常機制,還沒有這個內力哈! 主要是結合建構函式和解構函式,來總結異常對他倆的影響。建構函式和解構函式本來就很折磨腦筋,再疊加上異常機制,確實比較複雜。 

異常與解構函式

本節內容較少,因此先說。建構函式放到下一節討論。 

絕對不要將異常拋出解構函式

這一條在《Effective C++》 《More Effective C++》中均被作為獨立章節講解,可見其重要性。

有一點不要誤解:解構函式的代碼當然可以throw異常,只是這個異常不要被拋出解構函式之外。如果在解構函式中catch住異常,並且不再拋出,這就不會帶來問題。 

至於原因,有兩點。我們先看第一點。 

異常被拋出解構函式之外,往往意味著解構函式的工作沒有做完。如果解構函式需要釋放一些資源,異常可能導致資源流失,使得程式處於一個不安全的狀態。 

如下面的虛擬碼所示,異常導致p不能free,從而造成記憶體泄露。

Cpp代碼  
  1. class A  
  2. {  
  3. public:  
  4.     ~A()  
  5.    {  
  6.         throw exception;  
  7.         free(p);  
  8.    }  
  9. };  

OK,這個問題好辦,我好好寫代碼,確保解構函式釋放所有的資源之後,才拋出異常。這還不行嗎?

我們來看第二個原因。 如果兩個異常同時存在:第一個異常還沒有被catch,第二個異常又被拋出,這會導致C++會調用terminate函數,把程式結束掉!異常與建構函式

建構函式本來就是一件難以琢磨的東東,背後做了很多事情:成員對象的構造、基類成分的構造、虛表指標的設定等。這些事情本來就很糾結了,再讓建構函式拋出異常,會出現怎樣的悲劇呢?

有一點比較安慰:異常即使被拋出建構函式之外,也不會造成程式結束。那麼,是否存在資源泄漏的問題呢?不可一概而論,我們分情況分析。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.