c++中,動態記憶體的開闢需要使用者自己管理,在使用完成之後,必須由使用者自己來釋放空間,當然,大部分程式設計師都會說,我肯定會記得釋放的,然而,對於這個問題,我們還是防不勝防,一不小心就會造成記憶體洩露。在這樣的情況下,我們為何不把開闢的空間交給智慧型指標來管理呢?這樣即高效又不容易出問題。
c++中,智慧型指標是通過raii((resource acquisition is initialization)來實現的,資源分配即初始化,定義乙個類來封裝資源的分配和釋放,在建構函式中完成對資源的分配和初始化,並且管理資源;在析構函式中完成對資源的銷毀,這樣可以保證資源的初始化和管理的正確性。
在c++標準庫中,給出了auto_ptr(但是有很大的缺陷),unique_ptr等。
今天我們來模擬實現auto_ptr.我們需要了解它的實現機制。它是通過資源的轉移來實現的,我們先來看下**
為了可以管理任意種型別的指標,我們將它定義為模板類。
templateclass autoptr
autoptr( autoptr&p)
autoptr&operator=( autoptr&p)
_ptr = p._ptr;
p._ptr = null;
} return *this;
} ~autoptr() }
t& operator*()
t operator->()
private:
t* _ptr;
};
在這種機制下,我們在實現類的拷貝建構函式和賦值運算子過載函式時,先將原有的資源交給新的物件來管理,同時將原有物件的管理許可權交出去。
這種想法可以很好的解決在拷貝構造和賦值運算完成後兩個指標同時指向同一塊空間,在銷毀物件時,容易讓空間銷毀兩次,造成程式崩潰。
但是這種機制存在很大的問題,不管在c中還是c++中,對於一般的指標,可以通過指向同一塊空間的指標來修改或者訪問空間的內容,看如下**
int a=10;
int* pa=&a;
int* pb=&a;
*pa=20;
*pb=20;
但是在以上**中,此功能不可能實現。
注:c++11建議,在什麼情況下都不要使用auto_ptr函式。
為了解決以上問題,我們提出了兩種方案。
第一種方案:在類的私有成員中新增bool 變數,來確定多個物件是否占用同一塊空間。但是這種方式也存在很大問題。
第二種方案:防拷貝
在防拷貝中,我們想出來了三種方法:
1.將拷貝建構函式和賦值過載函式給為私有的,但是類的友元函式卻可以在類外訪問,不可行;
2.將拷貝建構函式和賦值過載函式只給出宣告,不給定義,但是可以在類外定義這兩個函式,不可行;
3.結合以上兩種方法,將拷貝建構函式和賦值過載函式給為私有的並且只給出宣告。
template class scopedptr
~scopedptr() }
t& operator*()
t operator->()
private:
scopedptr(const scopedptr&p);
scopedptr& operator=(const scopedptr&p);
private:
t* _ptr;
};
在智慧型指標中,還有乙個指標shared_ptr,這個在下節中給出介紹。
智慧型指標剖析
c 11中引入了智慧型指標包括auto ptr shared ptr weak ptr unique ptr。我們在寫c 程式時,動態記憶體需要自己維護,動態開闢的空間,在出函式作用域或者程式正常退出前必須釋放,否則會造成記憶體洩露。void fun 在do something時,如果出現了異常或者...
智慧型指標share ptr 簡單剖析
本文 話不多說直接上碼!shared ptr的簡單實現版本 基於引用記數的智慧型指標 namespace boost 空間庫boost templateshared ptr y py shared ptr constshared ptr r px r.px templateshared ptr co...
智慧型指標scoped ptr原始碼剖析
智慧型指標scoped ptr原始碼剖析 以下為簡化後的原始碼實現 include include include include using namespace std scoped ptr 指向乙個物件,死活不肯交出資源佔有權 私有的複製建構函式和賦值運算子 除非你和我一樣 swap scope...