C 智慧型指標auto ptr的原理及使用

2021-09-16 13:25:09 字數 2995 閱讀 6533

感謝博主的分享,**:c++智慧型指標auto_ptr的原理及使用

附:智慧型指標之 auto_ptr (pc版與gcc版)

std::auto_ptr使用auto_ptr作為成員變數,以避免資源洩漏。

為了防止資源洩漏,我們通常在建構函式中申請,析構函式中釋放,但是只有構造函式呼叫成功,析構函式才會被呼叫,換句話說,如果在建構函式中產生了異常,那麼析構函式將不會呼叫,這樣就會造成資源洩漏的隱患。

比如,如果該類有2個成員變數,指向兩個資源,在建構函式中申請資源a成功,但申請資源b失敗,則建構函式失敗,那麼析構函式不會被呼叫,那麼資源a則洩漏。

為了解決這個問題,我們可以利用auto_ptr取代普通指標作為成員變數,這樣首先呼叫成功的成員變數的建構函式肯定會呼叫其析構函式,那麼就可以避免資源洩漏問題

1、auto_ptr類

auto_ptr是乙個模板類,定義如下:

template class auto_ptr ;
它儲存的是乙個指向type的指標。

顧名思義,auto_ptr是一種智慧型指標,它包含乙個動態分配記憶體的指標,並在它生命週期結束的時候,銷毀包含的指標所指向的記憶體。

例1:

void f()

這樣的**很常見,但它有可能造成記憶體洩露。首先你用了new,你就要記得用delete,但即使你記住了用delete,還是會出問題。如果f()在執行delete pt之前,就丟擲了異常,函式返回了。那麼這個分配的物件就沒被刪除。

使用auto_ptr,很優雅的解決了這些問題。

例2:

void f()

現在的**,不會洩露type型別的物件。不管是函式正常結束,還是丟擲異常結束,都會呼叫pt的析構函式,從而刪除分配的物件。

2, auto_ptr建構函式

建構函式1:explicit auto_ptr(type* _ptr = 0) throw( );

auto_ptrpt;//包含乙個int*的指標,並初始化為null

auto_ptrpt(new int(123)); //包含乙個int*的指標,並初始化為123的位址

auto_ptrpt = new int(123); //error!建構函式宣告為explicit

建構函式2:auto_ptr(auto_ptr& _right) throw( );

int* ptr = new int();

auto_ptrpt1(ptr); //建構函式1

auto_ptrpt2(pt1); //將pt1的使用權轉給pt2,注意pt1指向null了

//pt1呼叫了本身的release()函式,將內部指標位址傳給pt2

建構函式3:template

auto_ptr(auto_ptr& _right) throw( );
宣告這樣乙個拷貝建構函式的目的,就是為了派生類指標能轉換成基類的指標。

例:

class base ;

class derived : public base ;

auto_ptrpderived(new derived);

auto_ptrpbase(pderived); //讓這樣的**能通過編譯器

其本質是為了讓,auto_ptr類內部的derived*轉換為base*

建構函式4:auto_ptr(auto_ptr_ref_right) throw( );

3, auto_ptr成員函式

成員函式1:type* get( ) const throw( );

獲得包含指標的位址

int* ptr = new int(123);

auto_ptrpt(ptr);

assert(pt.get() == ptr); //相等,指向同一位址

成員函式2:type* release( ) throw( );

返回包含指標的位址,並將包含指標設為null

string* pstr = new string("hello");

auto_ptrpt(pstr);

pt.release(); //不在指向string物件

//此時,pt.get()等於null

delete pstr; //應該手動刪除pstr指向的記憶體塊

成員函式3:void reset(type* _ptr = 0);

double* pdouble1 = new double(3.14);

double* pdouble2 = new double(1.23);

auto_ptrpt1(pdouble1);

pt1.reset(pdouble2); //將刪除pt1所指向的記憶體塊就是pdouble1指向的那塊

//此時,pt.get()等於pdouble2

cout << *pdouble1; //error,pdouble已經是野指標了

4, 使用總結

1、auto_ptr儲存的指標應該為null或者指向動態分配的記憶體塊。

2、auto_ptr儲存的指標應該指向單一物件(是new出來的,而不是new出來的)。

3、兩個auto_ptr物件不會同時指向同一塊記憶體塊。要明白2個auto_ptr物件賦值會發生什麼。

4、千萬不要把auto_ptr物件放在容器中。

5、當將auto_ptr作為函式引數時,最好宣告為const auto_ptr&(by const ref).當函式返回值可以簡單的傳值(by value).

C 智慧型指標 auto ptr

智慧型指標 auto ptr vc版本 擁有權管理和轉移 當乙個智慧型指標給另乙個智慧型指標初始化的時候,兩個智慧型指標將會同時指向乙個空間,這樣在物件析構的時候,會導致一塊空間釋放多次的問題,所以乙個物件從始至終只能擁有乙個智慧型指標,這樣就保證不會乙個物件多次釋放的問題.我們讓指標給指標初始化的...

C 智慧型指標(auto ptr)

智慧型指標 在c 中使用堆記憶體是非常頻繁的操作,堆記憶體的申請和釋放都由程式設計師自己管理。使用普通指標,容易造成堆記憶體洩露,二次釋放等問題,使用智慧型指標能更好的管理堆記憶體。c 11中引入了智慧型指標的概念,方便管理堆記憶體。棧 堆區別 棧 系統開闢 系統釋放 堆 手動開闢 手動釋放 設計 ...

C 智慧型指標auto ptr

template class auto ptr 建構函式 templateinline auto ptr auto ptr t p pointee p 拷貝建構函式 templateinline auto ptr auto ptr auto ptr rhs pointee rhs.release t...