下面著重講述學習C++時碰到的相關難題和問題,以及學習C++的技巧,如何更好的進行C++代碼解析,下文除了學習C++代碼的基本編程技巧外還對C++代碼的新特性進行全面研究。
所以 v 應該調用它們的析構函數。但是假設在這個調用期間,第二個 Widgets 的析構函數又拋出一個異常。現在有兩個異常同時在活動中,對於C++代碼解析來說這太多了。在非常巧合的條件下發生這樣兩個同時活動的異常,程序的執行會終止或者引發未定義行為。
在本例中,將引發未定義行為。與此相同,使用任何標准庫容器比如,list,set),任何 TR1中的容器,甚至是一個數組,都可能會引發未定義問題。並非必須是容器或數組才會陷入麻煩。程序夭折或未定義行為是析構函數引發異常的結果。
即使沒有使用容器或數組也會如此。C++ 不喜歡引發異常的析構函數。 這比較容易理解,但是如果你的析構函數需要執行一個可能失敗而拋出異常的操作,該怎麼辦呢?例如,假設你與一個數據庫連接類一起C++代碼解析:
- class Widget {
- public:
- ...
- ~Widget() { ... } // assume this might emit an exception
- };
- void doSomething()
- {
- std::vector<Widget> v;
- ...
- } // v is automatically destroyed here
為了確保客戶不會忘記調用 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
既然能成功地進行C++代碼解析那就好了,但是如果這個調用導致了異常,DBConn 的析構函數將散播那個異常,也就是說,它將離開析構函數。這就產生了問題,因為析構函數拋出了一個燙手的山芋。