明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

C++箴言:防范異常離開(kāi)析構(gòu)函數(shù)

[摘要]C++ 并不禁止從析構(gòu)函數(shù)中引發(fā)異常,但是這確實(shí)妨礙了實(shí)踐。至于有什么好的理由,考慮:      class Widget    public:     ...     ~Widget() ... // assume this might emit an exception   ;     ...
C++ 并不禁止從析構(gòu)函數(shù)中引發(fā)異常,但是這確實(shí)妨礙了實(shí)踐。至于有什么好的理由,考慮:

  

  class Widget {

   public:

    ...

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

  };

  

  void doSomething()

  {

   std::vector v;

   ...

  } // v is automatically destroyed here

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

  

  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