程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 《Effective C++》讀書筆記08:別讓異常逃離析構函數

《Effective C++》讀書筆記08:別讓異常逃離析構函數

編輯:關於C++

這節和異常有關,這一塊是我不太熟悉的,只能先把自己理解的記錄下來。

1 class Widget
2 {
3 public:
4
5   ~Widget() {} //假設這裡會吐出一個異常
6 };
7
8 void doSomething()
9 {
10   std::vector<Widget> v;
11
12 }//v在這裡自動銷毀

上面的代碼中,假設v含有10個Widget,如果在前面幾個的析構函數中彈出異常,則程 序會過早結束或者出現不明確行為。

確實不鼓勵在析構函數中拋出異常,可是如果程序在析構函數中必須執行一個動作, 而該動作可能會在失敗時拋出異常,該怎麼辦呢?比如下例:

1 class DBConnection
2 {
3 public:
4   static DBConnection create();
5   void close();//關閉連接,失敗則拋出異常
6 };

為了確保用戶不忘記調用close()關閉連接,我們可以創建一個管理DBConnection資 源的類:

1 class DBConn
2 {
3 public:
4   ~DBConn()
5    {
6     db.close();
7   }
8 private:
9   DBConnection db;
10 };

這樣在使用時,如果close沒有異常,則會很完美,不然DBConn就會使得它離開close 函數,這會出現上述問題。

我們可以在DBConn的析構函數中,自己提前處理這個異常,但是這麼做對於“導 致close拋出異常”的情況無法做出反應。

一個比較好的策略是重新定義DBConn接口,給用戶一個機會自己處理這種異常,比如 ,給用戶定義一個函數close:

1 class DBConn
2 {
3 public:
4   void close()//讓用 戶有機會自己捕捉異常
5   {
6     db.close();
7     closed = true;
8   }
9
10   ~DBConn()
11   {
12     if(!closed)
13     {
14       try{
15          db.close();
16       }
17       catch() {
18         //記錄下對close的調用失敗
19       }
20   }
21 private:
22   DBConnection db;
23   bool closed;
24 };

這樣一來,就有了雙保險,用戶可以自己處理異常,如果他們不處理,則析構函數會 自動吞下異常。

總結:

1.在析構函數中盡可能不要吐出異常,如果真要吐出就在析構函數中捕獲所以的異常 ,並提前結束程序或吞下它們;

2.如果用戶需要自己處理異常,則在類中應該提供一個普通函數處理。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved