數據結構--智能指針
阿新 • • 發佈:2019-01-21
小結 poi 同時 .sh -o 替換 bject ear malloc 一 智能指針的示例
A.內存泄漏
1.動態申請堆空間,用完後不歸還
2.C++語言中沒有垃圾回收的機制
3.指針無法控制所指堆空間的生命周期
B.當代C++軟件平臺中的智能指針
1.指針生命周期結束時主動釋放堆空間
2.一片堆空間最多只能由一個指針標識
3.杜絕指針運算和指針比較
智能指針的設計方案
a.通過類模板描述指針的行為
能夠定義不同類型的指針對象
b.重載指針特征操作符(->和*)
利用對象模擬原生指針的行為
Point類實現代碼如下
#include "Object.h" namespace MyLib { template <typename T> class Pointer:public Object { protected: T* m_pointer; public: Pointer(T* p=NULL) { m_pointer=p; } T* operator->() { return m_pointer; } const T& operator*()const { return *m_pointer; } const T* operator->()const { return m_pointer; } T& operator*() { return *m_pointer; } bool isNull()const { return (m_pointer==NULL); } T* get()const { return m_pointer; } }; }
SmartPoint的實現代碼
#include "Pointer.h" namespace MyLib { /*智能指針的實現(智能指針只能指向單個變量或者單個對象) 1.指針生命周期結束時主動釋放空間 2.一片堆空間最多只能由一個指針標識 3.杜絕指針運算和指針比較 設計方案 1.通過類模板描述指針的行為(能夠定義不同類型的指針對象) 2.重載指針特征操作符(->和*)(利用對象模擬原生指針的行為) */ template<typename T>//創建的指針可以指向任意的類型 class SmartPointer:public Pointer<T>//定義的類 { public: SmartPointer(T* p=NULL):Pointer<T>(p) { } SmartPointer(const SmartPointer<T>& obj) { this->m_pointer=obj.m_pointer; const_cast<SmartPointer<T>&>(obj).m_pointer=NULL; } SmartPointer<T>& operator =(const SmartPointer<T>& obj) { if(this!=obj) { T* p=this->m_pointer; //delete m_pointer; this->m_pointer=obj.m_pointer; const_cast<SmartPointer<T>&>(obj).m_pointer=NULL; delete p; } return *this; } ~SmartPointer() { delete this->m_pointer; } }; }
在使用智能指針(SmartPointer)替換單鏈表(LinkList)中的原生指針會出現問題,可以發現在SmartPointer的設計方案中(一片堆空間最多只能由一個指針標識)
二.SharedPoint的實現
SharedPoint設計要點
A.類模板
通過計數機制(ref)標識堆內存
1.堆內存被指向時:ref++
2.指針被置空時:ref--
3.ref==0:釋放堆內存
計數機制的原理
同時由於SharedPoint支持多個對象同時指向一片堆空間,因此,必須支持比較操作
實現的代碼如下
#include "Pointer.h" #include <cstdlib> #include "Exception.h" namespace MyLib { 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*>(std::malloc(sizeof(int)));//在堆空間申請一個四個字節 if(this->m_ref)//內存申請成功的情況下的操作 { *(this->m_ref)=1; this->m_pointer=p; } else { THROW_EXCEPTION(NoEoughMemoryException,"..."); } } } 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); } }
註意:
1.只能指針只能用來指向堆空間中的單個變量
2.不同類型的智能指針對象不能混合使用
3.不要使用delete釋放智能指針指向的堆空間
三.小結
1.SharedPoint最大程度的模擬了原生指針的行為
2.計數機制確保多個智能指針合法的指向同一片堆空間
3.智能指針只能用於指向堆空間中的內存
4.不同類型的智能指針不要混合使用
5.堆對象的生命周期由智能指針進行管理
數據結構--智能指針