感謝博主的分享,**: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...