auto_ptr 是c++標準庫提供的類模板,auto_ptr物件通過初始化指向由new建立的動態記憶體,它是這塊記憶體的擁有者,一塊記憶體不能同時被分給兩個擁有者。當auto_ptr物件生命週期結束時,其析構函式會將auto_ptr物件擁有的動態記憶體自動釋放。即使發生異常,通過異常的棧展開過程也能將動態記憶體釋放。auto_ptr不支援new 陣列。
#include
1) 建構函式
1] 將已存在的指向動態記憶體的普通指標作為引數來構造
int* p = new int(33);
auto_ptrapi(p);
2] 直接構造智慧型指標
auto_ptr< int > api( new int( 33 ) );
2) 拷貝構造
利用已經存在的智慧型指標來構造新的智慧型指標
auto_ptr< string > pstr_auto( new string( "brontosaurus" ) );
auto_ptr< string > pstr_auto2( pstr_auto ); //利用pstr_auto來構造pstr_auto2
因為一塊動態記憶體智慧型由乙個智慧型指標獨享,所以在拷貝構造或賦值時都會發生擁有權轉移的過程。在此拷貝構造過程中,pstr_auto將失去對字串記憶體的所有權,而pstr_auto2將其獲得。物件銷毀時,pstr_auto2負責記憶體的自動銷毀。
3) 賦值
利用已經存在的智慧型指標來構造新的智慧型指標
auto_ptr< int > p1( new int( 1024 ) );
auto_ptr< int > p2( new int( 2048 ) );
p1 = p2;
在賦值之前,由p1 指向的物件被刪除。賦值之後,p1 擁有int 型物件的所有權。該物件值為2048。 p2 不再被用來指向該物件。
通常的指標在定義的時候若不指向任何物件,我們用null給其賦值。對於智慧型指標,因為建構函式有預設值0,我們可以直接定義空的auto_ptr如下:
auto_ptr< int > p_auto_int; //不指向任何物件
因為auto_ptr的所有權獨有,所以下面的**會造成混亂。
int* p = new int(0);
auto_ptrap1(p);
auto_ptrap2(p);
因為ap1與ap2都認為指標p是歸它管的,在析構時都試圖刪除p, 兩次刪除同乙個物件的行為在c++標準中是未定義的。所以我們必須防止這樣使用auto_ptr。
1) 按值傳遞時,函式呼叫過程中在函式的作用域中會產生乙個區域性物件來接收傳入的auto_ptr(拷貝構造),這樣,傳入的實參auto_ptr就失去了其對原物件的所有權,而該物件會在函式退出時被區域性auto_ptr刪除。如下例:
void f(auto_ptrap)
auto_ptrap1(new int(0));
f(ap1);
cout<<*ap1; //錯誤,經過f(ap1)函式呼叫,ap1已經不再擁有任何物件了。
2) 引用或指標時,不會存在上面的拷貝過程。但我們並不知道在函式中對傳入的auto_ptr做了什麼,如果當中某些操作使其失去了對物件的所有權,那麼這還是可能會導致致命的執行期錯誤。
結論:const reference是智慧型指標作為引數傳遞的底線。
原因很簡單,delete 表示式會被應用在不是動態分配的指標上這將導致未定義的程式行為。
1) get()
int* p = new int(33);
cout << "the adress of p: "<< p << endl;
auto_ptrap1(p);
cout << "the adress of ap1: " << &ap1 << endl;
cout << "the adress of the object which ap1 point to: " << ap1.get() << endl;
輸出如下:
the adress of p: 00481e00
the adress of ap1: 0012ff68
the adress of the object which ap1 point to: 00481e00
第一行與第三行相同,都是int所在的那塊記憶體的位址。第二行是ap1這個類物件本身所在記憶體的位址。
2) reset()
重新設定auto_ptr指向的物件。類似於賦值操作,但賦值操作不允許將乙個普通指標指直接賦給auto_ptr,而reset()允許。如下例:
auto_ptr< string > pstr_auto( new string( "brontosaurus" ) );
pstr_auto.reset( new string( "long -neck" ) );
在例子中,重置前pstr_auto擁有"brontosaurus"字元記憶體的所有權,這塊記憶體首先會被釋放。之後pstr_auto再擁有"long -neck"字元記憶體的所有權。
注:reset(0)可以釋放物件,銷毀記憶體。
3) release()
返回auto_ptr指向的那個物件的記憶體位址,並釋放對這個物件的所有權。
用此函式初始化auto_ptr時可以避免兩個auto_ptr物件擁有同乙個物件的情況(與get函式相比)。
例子如下:
auto_ptr< string > pstr_auto( new string( "brontosaurus" ) );
auto_ptr< string > pstr_auto2( pstr_auto.get() ); //這是兩個auto_ptr擁有同乙個物件
auto_ptr< string > pstr_auto2( pstr_auto.release() ); //release可以首先釋放所有權
原文**:
auto ptr智慧型指標
1 class auto ptr 這個智慧型指標應該保證,無論在何種情形下,只要自己被摧毀,就一定連帶釋放其所指資源。而由於智慧型指標本身就是區域變數,所以無論是正常退出,還是異常退出,只要函式退出,它就一定會被銷毀。注意 auto ptr不允許使用一般指標慣用的賦值 assign 初始化方式。必須...
智慧型指標 AutoPtr
include include include using namespace std void func autoptr 析構函式來負責釋放 void test catch exception e autoptr 析構函式來負責釋放 private t ptr struct aa void fun...
stl智慧型指標auto ptr
感覺auto ptr還是存在一些不足的,效率十分低,而且丟失了一般指標方便常用的操作,如 等,auto ptr只過載了 這幾個操作符,所以使用很不方便。一 說明 int a null delete a do nothing 應此auto ptr的析構函式是這樣子的 auto ptr 二 auto p...