一 智能指针的示例
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. 堆对象的生命周期由智能指针进行管理
来源: http://www.bubuko.com/infodetail-2928686.html