資料結構 筆記:SharedPointer類實現
阿新 • • 發佈:2018-12-16
使用智慧指標(SmartPointer)替換單鏈表(LinkList)中的原生指標是否可行?
問題
-SmartPointer的設計方案
·指標宣告週期結束時主動釋放堆空間
·一片堆空間最多隻能由一個指標標識
·杜絕指標運算和指標比較
新的設計方案
-Pointer是智慧指標的抽象父類(模板)
·純虛解構函式virtual ~Pointer() = 0;
·過載operator -> ()
·過載operator * ()
template <typename T> class Pointer : public Object { protected: T* m_pointer; public: Pointer(T* p = NULL) { m_pointer = p; } T* operator-> () { return m_pointer; } T& operator* () { return *m_pointer; } bool isNULL() { return (m_pointer == NULL); } T* get() { return m_pointer; } };
SharedPointer類的具體實現
-類模板
·通過技術機制(ref)標識堆記憶體
~堆記憶體被指向時:ref++
~指標被置空時:ref--
~ref == 0 時:釋放堆記憶體
template <typename T> class SharedPointer : public Pointer<T> { protected: int* m_ref; //計數機制成員指標 void assign(const SharedPointer<T>& obj) { this->m_ref = obj.m_ref; this->m_pointer = obj.m_pointer; if(this->m_ref) { (*this->m_ref)++; } } public: SharedPointer(T* p = NULL) : m_ref(NULL) { if(p) { this->m_ref = static_cast<int*>(malloc(sizeof(int))); if(this->m_ref ) { *(this->m_ref) = 1; this->m_pointer = p; } else { //丟擲異常 } } } SharedPointer(const SharedPointer<T>& obj) : Pointer<T>(NULL) { assign(obj); } SharedPointer<T>& operator = (const SharedPointer<T>& obj) { if(this != &obj) { clear(); assign(obj); } return *this; } void clear()//將當前指標置為空 { T* toDel = this->m_pointer; int* ref = this->m_ref; this->m_pointer = NULL; this->m_ref = NULL; if(ref) { (*ref)--; if(*ref == 0) { free(ref); delete toDel; } } } ~SharedPointer() { clear(); } }; template <typename T> bool operator == (const SharedPointer<T>& l,const SharedPointer<T>& r) { return (l.get() == r.get()); } template <typename T> bool operator != (const SharedPointer<T>& l,const SharedPointer<T>& r) { return !(l == r); }
智慧指標的比較
由於SharedPointer支援多個物件同時指向一片堆空間;因此,必須支援比較操作!
智慧指標的使用軍規
-只能用來指向堆空間中的單個變數(物件)
-不同型別的智慧指標物件不能混合使用
-不要使用delete釋放智慧指標指向的堆空間
總結:
-SharedPointer最大程度的模擬了原生指標的行為
-計數機制確保多個智慧指標合法的指向同一片堆空間
-智慧指標智慧用於指向堆空間中的記憶體
-不同型別的智慧指標不要混合使用
-堆物件的宣告週期由智慧指標進行管理