天天看點

Effective C++筆記 3

本文内容基本來自于《Effective C++》一書,為學習後的筆記,以便溫故。

《Effective C++ 》第 3節  資源管理

(1)條款13:以對象管理資源

          為防止資源洩漏,請使用RAII(Resource Acquisition Is Initialliztion資源取得時機便是初始化時機)對象,它們在構造函數中獲得資源并在析構函數中釋放資源。

          兩個常被使用的RAII classes分别時tr1::shared_ptr(引用計數型智慧指針RCSP)和auto_ptr(标準庫中的智能指針)。前者通常是較佳選擇,因為其copy行為比較直覺。若選擇auto_ptr,複制動作會使他指向NULL。

(2)條款14:在資源管理類中小心copying行為

         複制RAII對象必須一并複制它所管理的資源,是以資源的copying行為決定RAII對象的copying行為。(例如:常見的一個錯誤就是,對象A中存在對另外一個對象B的引用,此時使用預設的copy函數複制該對象A為C,那麼在C析構的時候會将B删除掉,A在析構的時候就會出錯)

         普遍而常見的RAII class copying行為是:抑制copying, 施行引用計數法(shared_ptr類似方法)。不過其他行為也可能被實作。

(3)條款15:在資源管理類中提供對原始資源的通路

         APIs往往要求通路原始資源,是以每一個RAII class應該提供一個“取得其所管理之資源”的辦法。(例如:shared_ptr,auto_ptr重載了指針取值操作符( -> 和 *),或者提供一個get()函數,傳回一個原始指針)

       對原始資源的通路可能經由顯示轉換或者隐式轉換。一般而言顯式轉換比較安全,但是隐式轉換對客戶比較友善。

(4)條款16:成對使用new和delete時要采取相同的形式

          int* p = new int[5];  delete p;  //這樣是錯誤的,隻删除了第一個元素的記憶體空間。

          如果你在new表達式中使用[],必須在相應的delete表達式中也使用[],如果你在new表達式中不使用[],也一定不要在delete中使用[]

(5)條款17:以獨立語句将newed對象置入智能指針。

          例如:函數 void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);在具體調用的時候使用如下方式:

                      processWidget(std::tr1::shared_ptr<Widget> (new Widget), priority);該函數中在調用該函數之前需要做三件事情:

                       A :調用 priority         B:執行 new Widget      C: 調用tr1::shared_ptr構造函數

                      此時,如果這樣對函數進行調用,會有資源洩漏的可能性。因為C++編譯器對于這三個事情的執行順序沒有嚴格的規定。如果 new在第一個位置執行,priority在第二個執行,此時在執行第二個出錯的時候,new出來的資源就無法放入智能指針中,也就造成了資源洩漏。

           以獨立的語句将newed對象存儲于智能指針中,如果不這樣做一旦抛出異常,就有可能導緻資源洩漏。