您好,登錄后才能下訂單哦!
智能指針的三種常見寫法:
一、最開始的原始寫法,原始寫法可以理解為指針轉移的方法。
template<typename T> class AutoPtr { public: AutoPtr() :_ptr(NULL) {} AutoPtr(T* ptr) :_ptr(ptr) {} ~AutoPtr() { if (_ptr) { delete _ptr; _ptr = NULL; } } AutoPtr<T>(AutoPtr<T>& ap) : _ptr(ap._ptr) { ap._ptr = NULL; } AutoPtr<T>& operator = (AutoPtr<T>& ap) { if (this != &ap) { delete _ptr; _ptr = ap._ptr; ap._ptr = NULL; } return *this; } T& operator*() { return *_ptr; } T* GerPtr() { return _ptr; } private: T* _ptr; };
二、演變為后來的scoped寫法,又可以稱作守衛寫法。該寫法相對于原始寫法的優點在于不讓使用拷貝構造和運算符的重載,這樣就避免了深淺拷貝的指針問題。做法是把拷貝構造、運算符的重載定聲明出來而不定義,并且用protected保護起來。scoped寫法是引用的boost庫。有興趣的可以去了解一下這個東西,背后還是有很多故事的,在這我就不多說啦。
template<class T> class scopedPtr { public: scopedPtr() :_ptr(NULL) {} scopedPtr(T* ptr) :_ptr(ptr) {} ~scopedPtr() { if (_ptr) { delete _ptr; _ptr = NULL; } } T& operator*() { return *_ptr; } T* operator->() { return _ptr; } T* GetPtr() { return _ptr; } protected: //加上protected可以防止使用者在類之外定義拷貝構造和運算符的重載函數 scopedPtr<T>(const scopedPtr<T>& sp); //不讓使用者使用拷貝,可以防止拷貝,所以只聲明不定義 scopedPtr<T>& operator=(const scopedPtr<T>& sp); private: T* _ptr; };
三、sharedPtr寫法
這種方法考慮了深淺拷貝問題并且引用了引用計數器來解決淺拷貝的問題,比較完善的實現了智能指針想要實現的功能。
template<class T> class SharePtr { public: SharePtr(T* ptr) :_ptr(ptr) , _pCount(new int(1)) {} //SharePtr(Shar) // :_ptr(sp._ptr) //{ // *_pCount = 1; //} ~SharePtr() { if (_ptr) { if (--(*_pCount) == 0) { delete _ptr; delete _pCount; _ptr = NULL; _pCount = NULL; } _ptr = NULL; } } SharePtr<T>(const SharePtr<T>& sp) { _ptr = sp._ptr; _pCount = sp._pCount; ++(*_pCount); } SharePtr<T>& operator=(const SharePtr<T>& sp) { if (this != &sp) { if (--(*_pCount) == 0) //這里要分清楚是誰減一,邏輯需要分析清楚 { delete _ptr; delete _pCount; _ptr = NULL; _pCount = NULL; } _ptr = sp._ptr; _pCount = sp._pCount; ++(*_pCount); } return *this; } private: T* _ptr; int* _pCount; };
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。