[More Effective C++ 學習筆記]異常

來源:互聯網
上載者:User

<異常>

       條款9:利用destructors避免泄露資源

       在函數中,可以將資源封裝在局部對象中,通常便可以在exceptions出現時避免泄露資源。是因為局部對象總是會在函數結束時被析構,不論函數如何結束,但唯一例外的就是調用longjmp而結束。

 

       條款10:在constructors內阻止資源流失(resource leak)

       C++只會析構已構造完成的對象。對象只有在其constructor執行完畢才算是完全構造妥當。

  面對尚未完全構造好的對象,為什麼C++拒絕調用其解構函式?是因為若解構函式被調用於一個尚未完全的構造好的對象身上,那麼這個解構函式如何知道建構函式現在構造了那些資源?若添加變數來統計資料的構造程度,將造成效率的降低。

 

       條款11:禁止異常(exceptions)流出destructors之外

       在兩種情況下,解構函式會被調用:

  1. 當對象正常狀態下被銷毀,也就是當它離開了它的生存空間(scope)或是被明白地給予刪除;
  2. 當對象唄exception處理機制銷毀,即exception傳播過程中的stack-unwinding(棧輾轉開鎖)機制。

 

  有兩個理由支援我們全力阻止exceptions傳出destructors之外:

  1. 它可以避免terminate函數在exception傳播過程的棧輾轉開解機制中被調用;
  2. 它可以協助確保destructors完成其應該完成的所有事情。

 

  條款12:瞭解拋出一個exception與傳遞一個參數或調用一個虛函數之間的差異

  函數參數和exceptions的傳遞方式有三種:by value、by reference、by pointer。但是需要注意兩者的不同,是因為如果你調用一個函數,控制權最終會回到調用端(除非失敗以至於無法返回),但是當你拋出一個exception,控制權不會再回到拋出端。

 

  exceptions與catch字句匹配的過程中,僅有兩種轉換可以發生:

  1. 繼承架構中的類轉換;
  2. 從一個有型指標轉換為無型指標。所以一個針對const void *指標而設計的catch子句,可以捕捉任何指標型別的exception。

 

  傳遞對象到函數或是以對象調用虛函數和將對象拋出成為一個exception之間的差異:

  1. exception objects總是會被拷貝:如果以by value方式捕捉,它們甚至被拷貝兩次;
  2. 被拋出成為exceptions的對象,其被允許的型別轉換動作要比被傳遞到函數去的對象少;
  3. catch子句以其出現於原始碼的次序被編譯器檢驗比對,齊總第一個匹配成功者便獲得執行。

 

  條款13:以by reference方式捕捉exceptions

  catch-by-pointer方式是唯一在搬移異常相關資訊時不需要拷貝對象的一種做法。它有兩種做法:

  1. 拋出局部對象的指標,即從棧上分配的記憶體空間。但是該對象離開範圍將被析構,因此需要讓異常對象在離開範圍後仍然存在,即全域對象或靜態對象。
  2. 拋出一個新的指向堆的對象。但是需要考慮什麼時候釋放記憶體,以防止記憶體泄露。

 

  catch-by-value方式:當異常對象被拋出時,就的拷貝兩次。同時它可能印發對象切割問題。因為derived class exception objects被捕捉並被視為base class exceptions者,將失去其派產生分(參考《深入探索C++物件模型》)。

 

  catch-by-reference方式:它不像catch-by-pointer,不會發送對象刪除問題,因此也就不難捕捉標準的異常;它也不想catch-by-value,沒有切割問題,而且異常只會被拷貝一次。

 

       條款14:明智運用exception specifications

       如果函數拋出一個未列於其exception specification的exception,這個錯誤將會在運行期被檢測出來,於是特殊函數unexpected會被自動調用。其中,unexpected函數的預設行為是調用terminate函數,而terminate函數的預設行為是調用abort函數,因此程式如果違反exception specification,預設結果就是程式被中斷。

 

       避免踏上unexpected之路的方法:

  1. 避免將exception specification放在需要型別自變數的templates身上;
  2. 如果函數A內調用了函數B,而函數B屋exception specification,那麼A函數本身也不要設定exception specification;
  3. 處理系統可能拋出的exceptions。

 

  C++允許你以不同型別的exceptions取代非預期的exceptions。

 

       條款15:瞭解異常處理(exception handling)的成本

       為了能夠在運行期處理exceptions,程式必須做大量的簿記工作。在每一個執行點,它們必須能夠確認如果發送exception,哪些對象需要析構;它們必須在每一個try語句塊的進入點和離開點做記號;針對每個try語句塊它們必須記錄對應的catch子句以及能夠處理的exceptions型別。

 

       PS. 這裡只是一個大體,如果想要瞭解更多的知識或者更好的運用,需要看《More effective C++》一書中對異常的具體條款描述。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.