條款13:以對象管理資源
(Use objects to manage resources)
- 獲得資源後立刻放進管理對象內。 實際上“以對象管理資源”的觀念常被稱爲“資源取得時機便是初始化時機”(Resource Acquisition Is Initialization;RAII)
- 管理對象運用析構函數確保資源被釋放。
- 兩個常被使用的RAII classes分別是tr1::shared_ptr和auto_ptr。前者通常是較佳選擇,因爲其copy行爲比較直觀。若選擇auto_ptr,複製動作會使它(被複制物)指向null。
條款14:在資源管理類中小心copying行爲
(Think carefully about copying behavior in resource-managing classes)
- 複製RAII對象必須一併複製它所管理的資源,所以資源的copying行爲決定RAII對象的copying行爲。
- 普遍而常見的RAII class copying行爲是:抑制copying、施行引用計數法。不過其他行爲(複製底部資源、轉移底部資源的擁有權等)也都可能被實現。
條款15:在資源管理類中提供對原始資源的訪問
(Provide access to raw resources in resource-managing classes)
- APIs往往要求訪問原始資源(raw resources),所以每一個RAII class應該提供一個“取得其所管理之資源”的方法。
- 對原始資源的訪問可能經由顯示轉換或隱式轉換。一般而言顯示轉換比較安全,但隱式轉換對客戶比較方便。
條款16:成對使用new和delete時要採取相同形式
(Use the same form in corresponding uses of new and delete)
- 如果你在new表達式中使用[],必須在相應的delete表達式中也使用[]。如果你在new表達式中不使用[],一定不要再相應的delete表達式中使用[]。
條款17:以獨立語句將newed對象置入智能指針
(Store newed objects in smart pointers in standalone statements)
- 以獨立語句將newed對象存儲於(置入)智能指針內。如果不這樣做,一旦異常被拋出,有可能導致難以察覺的資源泄漏。
- 例如:
processWidget(std::tr1::shared_ptr< Widget >(new Widget), priority());
該語句將執行三件事:
1. 調用priority
2. 執行"new Widget"
3. 調用tr1::shared_ptr構造函數
而執行次序由編譯器決定,如果1.在2.和3.中間被執行,並且其發生異常,那麼"new Widget"返回的指針將會遺失,從而可能引發資源泄漏。因此,我們應當拆分其爲兩個語句:
std::tr1::shared_ptr< Widget > pw(new Widget); // 1.
processWidget(pw, priority()); // 2.