使用智能指针(SmartPointer)替换单链表(LinkList)中的原生指针是否可行?
问题
-SmartPointer的设计方案
·指针声明周期结束时主动释放堆空间
·一片堆空间最多只能由一个指针标识
·杜绝指针运算和指针比较
新的设计方案
-Pointer是智能指针的抽象父类(模板)
·纯虚析构函数virtual ~Pointer() = 0;
·重载operator -> ()
扫描二维码关注公众号,回复:
3631925 查看本文章
·重载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最大程度的模拟了原生指针的行为
-计数机制确保多个智能指针合法的指向同一片堆空间
-智能指针智能用于指向堆空间中的内存
-不同类型的智能指针不要混合使用
-堆对象的声明周期由智能指针进行管理