关键词:SharedPointer
类的实现
0. SharedPointer
类图
SharedPointer类图
2. SharedPointer
设计要点——计数机制
- 通过计数机制(ref)标识堆内存
当堆内存被指向时:++ref
当指针被置空时:--ref
当ref==0
时:释放堆空间
计数机制原理图
3. SharedPointer
类的声明
template < typename T >
class SharedPointer : public Pointer<T>
{
protected:
int* m_ref; // 计数机制成员指针
public:
SharedPointer(T* p = NULL);
SharedPointer(const SharedPointer<T>& obj);
SharedPointer<T>& operator= (const SharedPointer<T>& obj);
void clear(); // 将当前指针置为空
~SharedPointer();
};
由于
SharedPointer
支持多个对象同时指向一片堆空间,因此,必须支持比较操作。
4. SharedPointer
类的实现
#ifndef SHAREDPOINTER_H
#define SHAREDPOINTER_H
#include "cstdlib"
#include "Exception.h"
#include "Pointer.h"
namespace DTLib
{
template < typename T >
class SharedPointer : public Pointer<T>
{
protected:
int* m_ref; // 计数机制成员指针
void assign(const SharedPointer<T>& obj);
public:
SharedPointer(T* p = NULL);
SharedPointer(const SharedPointer<T>& obj);
SharedPointer<T>& operator= (const SharedPointer<T>& obj);
void clear(); // 将当前指针置为空
~SharedPointer();
};
template < typename T >
SharedPointer<T>::SharedPointer(T* p) : m_ref(NULL)
{
if( p )
{
this->m_ref = static_cast<int*>(std::malloc(sizeof(int))); // 给m_ref分配堆内存空间
if( this->m_ref )
{
*(this->m_ref) = 1; // 申请成功后,计数赋值为1
this->m_pointer = p;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryExcetion, "No memory to create SharedPointer object...");
}
}
}
template < typename T >
void SharedPointer<T>::assign(const SharedPointer<T>& obj)
{
this->m_ref = obj.m_ref;
this->m_pointer = obj.m_pointer;
if( this->m_ref )
{
++(*this->m_ref);
}
}
template < typename T >
SharedPointer<T>::SharedPointer(const SharedPointer<T>& obj)
{
assign(obj);
}
template < typename T >
SharedPointer<T>& SharedPointer<T>::operator= (const SharedPointer<T>& obj)
{
if( this != &obj) // 避免自赋值
{
clear();
assign(obj);
}
return *this;
}
template < typename T >
void SharedPointer<T>::clear()
{
T* toDel = this->m_pointer;
int* ref = this->m_ref;
this->m_pointer = NULL;
this->m_ref = NULL;
if( ret ) // 判断计数变量是否合法
{
--(*ref); // 将计数变量减1
if( *ref == 0 ) // 判断计数变量是否为0
{
free(ref); // 释放计数变量的堆空间
delete toDel; // 销毁堆空间
}
}
}
template < typename T >
SharedPointer<T>::~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);
}
}
#endif // SHAREDPOINTER_H
5. 智能指针的使用军规
- 只能用来指向堆空间中的单个变量/对象
- 不同类型的智能指针对象不能混合使用
- 不要使用
delete
释放智能指针指向的堆空间
6. 小结
-
SharedPointer
最大程度的模拟了原生指针的行为 - 计数机制确保了多个智能指针合法的指向同一片堆空间
- 智能指针只能用于指向堆空间中的内存
- 不同类型的智能指针不要混合使用
- 堆对象的生命周期由智能指针进行管理
声明:此文章仅是本人在学习狄泰学院《数据结构实战开发教程》所做的笔记,文章中包含狄泰软件资料内容,一切版权归狄泰软件所有!
实验环境:ubuntu10 + Qt Creator2.4.1 + Qt SDK 4.7.4
网友评论