核心要理解引用计数,什么时候销毁底层指针,还有赋值,拷贝构造时候的引用计数的变化,析构的时候要判断底层指针的引用计数为0了才真正释放底层指针的内存。
template<class T>
class SmartPtr
{
private:
T *ptr;
int *use_count;
public:
SmartPtr(T *p);//默认构造函数
SmartPtr(const SmartPtr<T> &orig);//自定义构造函数
SmartPtr<T> &operator=(const SmartPtr<T> &rhs);//赋值运算符重载
~SmartPtr();//析构函数
T &operator*();//为了把智能指针当作普通指针操作,定义解引用操作
T *operator->();//定义取成员操作
T *operator+(int i);//定义指针加一个常数操作
int operator-(SmartPtr<T> &t1, SmartPtr<T> &t2);//定义两个指针相减操作
void getcount()//获得引用数
{
return *use_count;
}
};
template<class T>
SmartPtr<T>::SmartPtr(T *p)
{
ptr = p;
try
{
use_count = new int(1);
}
catch (...)
{
delete ptr;//申请失败,释放真实指针和引用计数的内存
ptr = nullptr;
delete use_count;
use_count = nullptr;
}
}
template<class T>
SmartPtr<T>::SmartPtr(const SmartPtr<T> &orig)
{
use_count = orig.use_count;//引用计数保存在一块内存,所有的SmartPtr对象的引用计数都指向这里
this->ptr = orig.ptr;
++(*use_count);
}
template<class T>
SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T> &rhs)
{
++*(rhs.use_count);
if (--*(use_count) == 0)//释放掉被赋值对象之前指向的内存
{
delete ptr;
ptr = nullptr;
delete use_count;
use_count = nullptr;
}
ptr = rhs.ptr;
*use_count = *(rhs.use_count);
return *this;
}
template<class T>
SmartPtr<T>::~SmartPtr()
{
getcount();
if (--(*use_count) == 0)
{
getcount();
delete ptr;
ptr = nullptr;
delete use_count;
use_count = nullptr;
}
}
template<class T>
T SmartPtr<T>::operator*()
{
return *ptr;
}
template<class T>
T* SmartPtr<T>::operator->()
{
return ptr;
}
template<class T>
T* SmartPtr<T>::operator+(int i)
{
T *temp = ptr + i;
return temp;
}
template<class T>
int SmartPtr<T>::operator-(SmartPtr<T> &t1, SmartPtr<T> &t2)
{
return t1.ptr - t2.ptr;
}