目录
先看看《Effective C++》对资源管理的讲解:
内存回收使用shared_ptr类
为什么use_count要定义为int*类型而不是int类型?
需要实现的函数如下:
template <typename T>
class CSmartPtr
{
private:
T * ptr;//底层真实的指针
int * use_count;//保存当前对象被多少指针引用计数
public:
CSmartPtr(T *p);//CSmartPtr<int> p(new int(2));
CSmartPtr(const CSmartPtr<T> &obj);//CSmartPtr<int> q(p)
CSmartPtr<T> &operator =(const CSmartPtr<T> &rhs);//q=p
~CSmartPtr();
T operator*();//解引用,智能指针可以想普通指针一样使用
T* operator->();//取成员操作
T* operator+(int i);//定义指针加一个常数
int getcount()
{
return *use_count;
}
T* get();
bool unique();
void swap(CSmartPtr<T> &mp);
};
源代码:
#pragma once
template <typename T>
class CSmartPtr
{
private:
T * ptr;//底层真实的指针
int * use_count;//保存当前对象被多少指针引用计数
public:
CSmartPtr(T *p);//CSmartPtr<int> p(new int(2));
CSmartPtr(const CSmartPtr<T> &obj);//CSmartPtr<int> q(p)
CSmartPtr<T> &operator =(const CSmartPtr<T> &rhs);//q=p
~CSmartPtr();
T operator*();//解引用,智能指针可以想普通指针一样使用
T* operator->();//取成员操作
T* operator+(int i);//定义指针加一个常数
int getcount()
{
return *use_count;
}
T* get();
bool unique();
void swap(CSmartPtr<T> &mp);
};
template <typename T>
void CSmartPtr<T>::swap(CSmartPtr<T> &mp)
{
std::swap(*this, mp);
}
template <typename T>
bool CSmartPtr<T>::unique()
{
return *use_count == 1;
}
template <typename T>
T* CSmartPtr<T>::get()
{
return ptr;
}
template <typename T>
CSmartPtr<T>::CSmartPtr(T *p)
{
ptr = p;
try
{
use_count = new int(1);
}
catch (CException* e)
{
//申请失败,释放真实指针和引用计数的内存
if (ptr!=nullptr)
{
delete ptr;
ptr = nullptr;
}
if (use_count!=nullptr)
{
delete use_count;
use_count = nullptr;
}
}
}
template <typename T>
CSmartPtr<T>::~CSmartPtr()
{
--(*use_count);
//检测当前对象的引用计数是不是只有真在结束生命周期的这个SmartPtr引用
if ((*use_count)==0)
{
delete ptr;
ptr = nullptr;
delete use_count;
use_count = nullptr;
}
}
template <typename T>
CSmartPtr<T>::CSmartPtr(const CSmartPtr<T> &obj)
{
use_count = obj.use_count;//引用计数保存一块内存地址,所有CSmartPtr对象引用计数都指向这里
this->ptr=obj.ptr;
++(*use_count);//当前引用计数加1
}
template <typename T>
T* CSmartPtr<T>::operator+(int i)
{
T* tmp = ptr + i;
return tmp;
}
template <typename T>
T* CSmartPtr<T>::operator->()
{
return ptr;
}
template <typename T>
T CSmartPtr<T>::operator*()
{
//返回指针内容
return *ptr;
}
template <typename T>
CSmartPtr<T> & CSmartPtr<T>::operator=(const CSmartPtr<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);
}
其他资源回收自定义资源管理类
实现一个互斥锁的资源管理类Lock,这里分两个版本实现,Lock1对象禁止复制,Lock2可以允许复制,复制增加资源的引用计数。
禁止复制版Lock1
引用计数版Lock2