1.scoped_ptr的實現原理及特性安全
特性:scoped_ptr和auto_ptr相似,但最大的區別就是不能轉讓管理權限,也就是說scoped_ptr禁止用戶進行拷貝和賦值函數
實現原理:如何才能禁止一個類進行拷貝和複製呢?咱們只須要將類的拷貝構造函數和賦值運算符重載的訪問限定符設置爲私有的能夠spa
樣例以下:設計
class ScopedPtr{ private: ScopedPtr(const ScopedPtr& sp); ScopedPtr& operator(const ScopedPtr& sp); };
scoped_ptr和auto_ptr相似,它包裝了new操做符在堆上分配的動態對象,可以保證動態建立的對象在任什麼時候候均可以被正確的刪除,可是scoped_ptr的全部權更加嚴格,不能轉讓,一旦scoped_ptr得到了對象的管理權,你就沒法再從它那裏去回來代理
正如scoped_ptr(局部指針)名字的含義同樣:這個指針只能在做用域裏使用,不但願被轉讓指針
實現以下:code
template<class T> class scoped_ptr { private: T *px; scoped_ptr(scoped_ptr const &); scoped_ptr & operator=(scoped_ptr const &); public: explicit scoped_ptr(T *p = 0); ~scoped_ptr(); void reset(T *p = 0); T & operator*()const; T * operator->()const; T * get()const; operator unspecified-bool-type()const; void swap(scoped_ptr & b); };
分析:對象
scoped_ptr的構造函數接受一個類型爲T*的指針p,建立出一個scoped_ptr對象,並在內部保存指針參數p,p必須是一個new表達式動態分配的結果或是一個空指針,當scoped_ptr的對象生命週期結束時,析構函數會使用delete操做自動銷燬所保存的指針對象,從而正確的回收資源。blog
scoped_ptr同時把拷貝構造函數和賦值操做都聲明爲私有,禁止對scoped_ptr的複製操做,保證了被它管理的指針不能被轉讓全部權生命週期
成員函數reset的功能是重置scoped_ptr,它刪除原來保存的指針,再保存新的指針值p,若是p是空指針,那麼scopted_ptr將不能持有任何指針,通常狀況下reset不該該配調用,由於它違背了scopted_ptr的本意---資源應該一直由scoped-ptr本身自動管理
實際上擁有權不可轉移不夠方便,swap成員函數能夠交換兩個scopted_ptr保存的原始指針,須要知道的是,scoped1.swap(scoped2) 只能用於它的定義所在的智能指針,而swap(scoped1,scoped2) 能夠更普遍的用於不少指針類型,包括裸指針和第三方智能指針
scoped_ptr用operator*()和operator->()重載了引用操做符和箭頭操做符,以模仿被代理的原始指針的行爲,所以能夠把scoped_ptr對象如同指針同樣使用,若是scoped_ptr保存空指針,那麼這兩個操做都是未定義的
scoped_ptr不支持比較操做,不能在兩個scoped_ptr之間,scoped_ptr和原始指針之間,scoped_ptr和空指針之間,進行相等或者不相等的比較操做,咱們也沒法爲它編寫額外的比較函數,由於其=和!=兩個操做符都是私有的
2.scoped_ptr與auto_ptr的區別
1.scoped_ptr和auto_ptr的用法幾乎同樣,大多數狀況下均可以與auto_ptr互換,它能夠從一個auto_ptr得到指針的管理權(同時auto_ptr失去指針管理權)
2.scoped_ptr和auto_ptr同樣不能用做容器的元素,可是緣由不一樣,auto_ptr是由於它的轉移語義,而scoped_ptr則是不支持拷貝和賦值,不符合容器對元素類型的要求
3.scoped_ptr和auto_ptr的根本區別在於全部權,auto_ptr被特地設計爲全部權是能夠被轉移的,能夠在函數之間傳遞,同一時刻只能有一個auto_ptr管理指針,而scoped_ptr把拷貝構造函數和賦值函數都聲明爲私有的,拒絕了指針全部權的轉讓,只有scoped_ptr本身可以管理指針,其餘人都無權訪問被管理的指針,從而保證了指針的絕對安全
4.若是代碼企圖從一個scoped_ptr構造或賦值另外一個scoped_ptr,那麼編譯器會報錯,阻止你這麼作,從而保護你的代碼,scoped_ptr更明確的表達了原始代碼編寫者的意圖:只能在定義的做用域內使用,不可轉讓,這在代碼後續的維持生命週期中很重要
樣例以下:
template<typename T> class ScopedPtr { public: ScopedPtr(T* ptr=NULL):_ptr(ptr){} ~ScopedPtr(){ if(_ptr!=NULL) { delete _ptr; _ptr=NULL; } } private: ScopedPtr(const ScopedPtr &sp); ScopedPtr& operator=(const ScopedPtr &sp); private: T *_ptr; }; int main() { ScopedPtr<int> sp1(new int(10)); ScopedPtr<int> sp2(new int(20)); //ScopedPtr<int> sp3(sp1); //編譯錯誤 拷貝函數私有 //sp1=sp2; //編譯錯誤 =操做符私有 }
因爲boost::scoped_ptr獨享指針全部權,當咱們真的須要複製時,需求便知足不了,如此咱們再引入一個智能指針boost::shared_ptr專門處理複製,參數傳遞的狀況,下一節咱們探討boost::shared_ptr智能指針