亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C++箴言:防止異常離開析構函數

2019-11-17 05:09:58
字體:
來源:轉載
供稿:網友

  C++ 并不禁止從析構函數中引發異常,但是這確實妨礙了實踐。至于有什么好的理由,考慮:

  

  class Widget {

   public:

    ...

    ~Widget() { ... } // assume this might emit an exception

  };

  

  void doSomething()

  {

   std::vector v;

   ...

  } // v is automatically destroyed here

  當 vector v 被析構時,它有責任銷毀它包含的所有 Widgets。假設 v 中有十個 Widgets,在銷毀第一個的時候,拋出一個異常。其他 9個 Widgets 仍然必須被銷毀(否則他們持有的任何資源將被泄漏),所以 v 應該調用它們的析構函數。但是假設在這個調用期間,第二個 Widgets 的析構函數又拋出一個異?!,F在有兩個異常同時在活動中,對于 C++ 來說這太多了。在非常巧合的條件下發生這樣兩個同時活動的異常,程序的執行會終止或者引發未定義行為。在本例中,將引發未定義行為。與此相同,使用任何標準庫容器(比如,list,set),任何 TR1中的容器,甚至是一個數組,都可能會引發未定義問題。并非必須是容器或數組才會陷入麻煩。程序夭折或未定義行為是析構函數引發異常的結果,即使沒有使用容器或數組也會如此。C++ 不喜歡引發異常的析構函數。 這比較輕易理解,但是假如你的析構函數需要執行一個可能失敗而拋出異常的操作,該怎么辦呢?例如,假設你與一個數據庫連接類一起工作:

  

  class DBConnection {

   public:

    ...

   

    static DBConnection create(); // function to return

    // DBConnection objects; params

    // omitted for simplicity

  void close(); // close connection; throw an

  }; // exception if closing fails

   更多文章 更多內容請看C/C++技術專題專題,或
  為了確??蛻舨粫浾{用 DBconnection 對象的 close,一個合理的主意是為 DBConnection 建立一個資源治理類,在它的析構函數中調用 close。這樣的資源治理類將在以后的文章中探討,但在這里,只要認為這樣一個類的析構函數看起來像這樣就足夠了:

  

  class DBConn { // class to manage DBConnection

   public: // objects

    ...

    ~DBConn() // make sure database connections

    { // are always closed

     db.close();

    }

   PRivate:

    DBConnection db;

  };

  它答應客戶像這樣編程:

  

  {

   // open a block

   DBConn dbc(DBConnection::create()); // create DBConnection object

   // and turn it over to a DBConn

   // object to manage

   ... // use the DBConnection object

   // via the DBConn interface

  } // at end of block, the DBConn

  // object is destroyed, thus

  // automatically calling close on

  // the DBConnection object

  既然能成功地調用 close 那就好了,但是假如這個調用導致了異常,DBConn 的析構函數將散播那個異常,也就是說,它將離開析構函數。這就產生了問題,因為析構函數拋出了一個燙手的山芋。 更多文章 更多內容請看C/C++技術專題專題,或
  有兩個主要的方法避免這個麻煩。DBConn 的析構函數能:

  終止程序 假如 close 拋出異常,調用 abort。

  

  DBConn::~DBConn()

  {

   try { db.close(); }

   catch (...) {


    make log entry that the call to close failed;

    std::abort();

   }

  }

  假如程序在析構過程遭碰到錯誤后不能繼續運行,這就是一個合理的選擇。它有一個好處是:假如答應從析構函數散播異??赡軙鹞炊x行為,這樣就能防止它發生。也就是說,調用 abort 就預先防止了未定義行為。

  抑制這個異常 起因于調用 close:

  

  DBConn::~DBConn()

  {

   try { db.close(); }

   catch (...) {

    make log entry that the call to close failed;

   }

  }

  通常,抑制異常是一個不好的主意,因為它會隱瞞重要的信息——某些事情失敗了!可是,有些時候,抑制異常比冒程序夭折或未定義行為的風險更可取。程序必須能夠在遭碰到錯誤并忽略之后還能繼續可靠地執行,這才能成為一個可行的選擇。

  這些方法都不太吸引人。它們的問題在于程序無法在第一現場對引起 close 拋出異常的條件做出回應。

  一個更好的策略是設計 DBConn 的接口,以使它的客戶有機會對可能會發生的問題做出回應。例如,DBConn 能夠自己提供一個 close 函數,從而給客戶一個機會去處理從那個操作中發出的異常。它還能保持對它的 DBConnection 是否已被關閉的跟蹤,假如沒有關閉就在析構函數中自己關閉它。這樣可以防止連接被泄漏。假如在 DBConnection 的析構函數中調用 close 失敗,無論如何,我們還可以再返回到終止或者抑制。

  

  class DBConn {

  public:

  ...

  

  void close() // new function for

  {

   // client use

   db.close();

   closed = true;

  }

  

  ~DBConn()

  {

   if (!closed) {

    try { // close the connection

     db.close(); // if the client didn’t

    }

    catch (...) { // if closing fails,

     make log entry that call to close failed; // note that and

     ... // terminate or swallow

    }

   }

  

   private:

    DBConnection db;

    bool closed;

  };

  將調用 close 的責任從 DBConn 的析構函數轉移到 DBConn 的客戶(同時在 DBConn 的析構函數中包含一個“候補”調用)可能會作為一種肆無忌憚地推卸責任的做法而刺激你。你甚至可以把它看作一個忠告(使接口易于正確使用)的違反。實際上,這都不正確。假如一個操作可能失敗而拋出一個異常,而且可能是一個需要處理的異常,這個異常就必須來自非析構函數。這是因為析構函數引發異常是危險的,永遠都要冒著程序夭折或未定義行為的風險。在此例中,讓客戶調用 close 并不是強加給他們的負擔,而是給他們一個時機去應付錯誤,否則他們將沒有機會做出回應。假如他們找不到可用到機會(或許因為他們相信不會有錯誤真的發生),他們可能忽略它,依靠 DBConn 的析構函數為他們調用 close。假如一個錯誤恰恰發生在那時——假如由 close 拋出——假如 DBConn 抑制了那個異常或者終止了程序,他們將無處訴苦。究竟,他們無處著手處理問題,他們將不再使用它。

  Things to Remember

  ·析構函數應該永不引發異常。假如析構函數調用了可能拋出異常的函數,析構函數應該捕捉任何異常,然后抑制它們或者終止程序。

  ·假如類客戶需要能對一個操作拋出的異常做出回應,則那個類應該提供一個常規的(非析構函數)函數來完成這個操作。 更多文章 更多內容請看C/C++技術專題專題,或

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩精品在线影院| 成人国产精品久久久| 5278欧美一区二区三区| 国产亚洲精品成人av久久ww| 国内伊人久久久久久网站视频| 国产成人一区二区三区| www.美女亚洲精品| 久久久免费在线观看| 精品视频中文字幕| 国产精品亚洲一区二区三区| 668精品在线视频| 国产欧洲精品视频| 日韩精品中文字幕在线| 色综合久久精品亚洲国产| 亚洲精品午夜精品| 国产97在线|亚洲| 久久久精品视频在线观看| 亚洲最大福利网| 欧美日本高清一区| 日韩美女中文字幕| 欧美成年人视频网站| 亚洲第一天堂无码专区| 欧洲成人性视频| 欧美在线精品免播放器视频| 欧美裸体xxxx极品少妇| 97成人超碰免| 欧美成人一区二区三区电影| 91免费视频网站| 亚洲国产精品视频在线观看| 亚洲伊人一本大道中文字幕| 欧美性xxxx极品hd欧美风情| 亚洲美女av在线| www日韩中文字幕在线看| 尤物yw午夜国产精品视频| 69av成年福利视频| 日韩亚洲精品视频| 91亚洲人电影| 久久人体大胆视频| 亚洲精品中文字幕av| 国产精品视频中文字幕91| 色综合久综合久久综合久鬼88| 欧美日韩国产123| 日韩禁在线播放| 欧美激情视频三区| 亚洲国产欧美一区二区三区久久| 日本午夜人人精品| 深夜福利亚洲导航| 欧美最猛性xxxxx亚洲精品| 国产精品十八以下禁看| 亚洲欧美国产另类| 欧美午夜片在线免费观看| 欧美专区日韩视频| 久久久久久美女| 日本一区二三区好的精华液| 国产精品视频久久| 精品国产区一区二区三区在线观看| 亚洲最大成人在线| www.色综合| 日韩av网址在线| 久久99国产精品久久久久久久久| 欧美丝袜美女中出在线| 成人性生交大片免费观看嘿嘿视频| 欧美电影在线免费观看网站| 97av在线影院| 亚洲精品视频中文字幕| 欧美电影免费观看大全| www.亚洲人.com| 色噜噜狠狠狠综合曰曰曰| 中文亚洲视频在线| 在线看日韩欧美| 欧美性视频精品| 欧美激情奇米色| 亚洲石原莉奈一区二区在线观看| 久久久久久亚洲精品中文字幕| 日韩av在线一区二区| 美女久久久久久久久久久| 久久亚洲精品网站| 午夜精品福利电影| 亚洲高清免费观看高清完整版| 国产精品扒开腿做爽爽爽男男| 亚洲一区二区免费在线| 97视频人免费观看| 亚洲天堂男人天堂| 国产激情久久久久| 一区二区亚洲欧洲国产日韩| 欲色天天网综合久久| 欧美在线欧美在线| 国产日韩专区在线| 亚洲国产小视频| 国产精品ⅴa在线观看h| 亚洲精品久久久久久久久久久久| 日韩网站免费观看高清| 视频在线观看一区二区| 国产香蕉97碰碰久久人人| 欧美日本高清一区| 韩国精品久久久999| 午夜精品99久久免费| 久久成人精品视频| 亚洲男人天堂2024| 欧美高清激情视频| 自拍视频国产精品| 国产成人高清激情视频在线观看| 日韩av在线免费播放| 精品福利一区二区| 久久偷看各类女兵18女厕嘘嘘| 91夜夜未满十八勿入爽爽影院| 九九热精品视频在线播放| 欧美日韩国产一区二区| 欧美黑人性猛交| 亚洲精品久久久久久久久久久久| 91免费视频国产| 综合激情国产一区| 日韩精品中文字幕在线观看| 亚洲精品视频免费| 欧美最猛性xxxxx(亚洲精品)| 国产精品视频导航| 成人福利网站在线观看11| 亚洲国产又黄又爽女人高潮的| 亚洲自拍偷拍色图| 影音先锋欧美精品| 久久久精品在线观看| 欧美激情在线视频二区| 91久久精品一区| 亚洲一区二区黄| 亚洲精品中文字幕av| 亚洲曰本av电影| 一个人www欧美| 色妞久久福利网| 国产精品直播网红| 久久久久久久999精品视频| 亚洲午夜未删减在线观看| 国产欧美日韩免费看aⅴ视频| 亚洲精品日韩久久久| 日韩av在线天堂网| 久久久久久久影院| 久久久久久久电影一区| 亚洲欧美日韩在线高清直播| 欧美日韩国产精品| 国产精品视频公开费视频| 久久免费成人精品视频| 欧美激情视频播放| 亚洲成人1234| 亚洲精品国产成人| 国产日韩欧美电影在线观看| 久久国产精品久久精品| 亚洲一区二区在线播放| 日韩精品在线免费观看视频| 青青久久aⅴ北条麻妃| 91色中文字幕| 丝袜美腿精品国产二区| 国产精品免费在线免费| 亚洲第一级黄色片| 亚洲国产成人爱av在线播放| 欧美在线不卡区| 亚洲a∨日韩av高清在线观看| 91精品国产综合久久香蕉| 国产精品18久久久久久麻辣| 国产精品丝袜一区二区三区| 欧美激情中文字幕在线| 国产精品黄色影片导航在线观看| 日韩美女激情视频| 午夜精品久久久久久久久久久久| 欧美日韩福利在线观看| 亚洲人成电影网站色|