我們定乙個投資行為的程式庫,其中各式各樣的投資型別繼承自乙個root類investment:
class investment( ... );
這個程式庫系通過乙個工廠函式**我們某特定的investment物件:
investment* createinvestment();
createinvestment的呼叫返回指標,指向investment繼承體系內的動態分配物件。呼叫者有責任刪除它。現在考慮有個f函式履行了這個責任:
void f()
這看起來妥當,但若干情況下f可能無法刪除它得自createinvestment的投資物件——或許因為「…」區域內的乙個過早的return語句,或許發生在createinvestment的使用及delete動作位於某迴圈內,而該迴圈由於某個continue或goto語句過早退出,再或許可能是「…」區域內的語句丟擲異常。無論delete如何被略過去,我們洩漏的不只是內含投資物件的那塊記憶體,還包括那些投資物件所儲存的任何資源。
不管情況如何,單純依賴「f總是會執行其delete語句」是行不通的。
為確保createinvestment返回的資源總是被釋放,我們需要將資源放進物件內,當控制流離開f,該物件的析構函式會自動釋放那些資源。
資源取得時機便是初始化時機(resource acquisition is initialization;raii)。
void f()
這個例子示範「以物件管理資源」的兩個關鍵想法:
(1)獲得資源後立刻放進管理物件內。
(2)管理物件運用析構函式確保資源被釋放。
由於auto_ptr被銷毀時會自動刪除它所指之物,所以一定要注意別讓多個auto_ptr同時指向同一物件。如果真是那樣,物件會被刪除一次以上。
我們來看:
std::auto_ptrpinvl(createinvestment()); //pinv1指向createinvestment返回物件。
std::auto_ptrpinv2(pinv1); //現在pinv2指向物件,pinv1被設為null
pinv1=pinv2; //現在pinv1指向物件,pinv2被設為null
由於:「受auto_ptr管理的資源必須絕對沒有乙個以上的auto_ptr同時指向它」,意味auto_ptr並非管理動態分配資源的神兵利器。舉個例子,stl容器要求其元素發揮「正常的」複製行為,因此這些容器容不得auto_ptr。
auto_ptr的替代方案是「引用計數型智慧型指標」(reference-counting smart pointer;rcsp),
f函式可寫成:
void f()
shared_ptr的複製行為比auto_ptr正常:
void f()
由於tr1::share_ptr的複製行為「一如預期」,它們可被用於stl容器以及其他「auto_ptr的非正統複製行為並使用「的語境上。
(1)為防止資源洩漏,請使用raii物件,它們在建構函式中獲得資源並在析構函式中釋放資源。
(2)兩個常被使用的raii classes分別是tr1::shared_ptr和auto_ptr。前者通常是較佳選擇,因為其copy行為比較直觀。若選擇auto_ptr,複製動作會使它(被複製物)指向null。
條款13 以物件管理資源
問題 解決 智慧型指標。把資源放入物件內,利用析構函式確保釋放。1 資源取得時機便是初始化時機 resource acquisition is initialization raii 2 管理物件運用析構函式確保資源被釋放。別讓auto ptr同時指向同一物件。為了預防這個問題,能過copy建構函式...
條款13 以物件管理資源
我們都知道,當new乙個東西之後,必須delete它。但是問題可能出現在在new和delete之間 比如中間出現了異常,或者return之類的。一種比較好的作法是通過物件來管理 因為當物件的宣告週期結束以後,會呼叫析構函式,而在析構函式中delete,這樣的作法就靠譜多了。在標準c 中,定義了2種管...
條款13 以物件管理資源
一 如下 假設各種子型別繼承 root class investmen class investment investment createinevstment factory函式 void f 在 區域內乙個過早return,或者期間丟擲異常,流程控制不可能經過這條語句,所以這樣的話就會導致資源洩...