auto_ptr
简介
交换资源的管理权,将被拷贝资源置空,很危险,一般被禁用
代码实现
cpp
namespace memory
{
template<typename T>
class auto_ptr
{
public:
auto_ptr(T* ptr)
:_ptr(ptr)
{}
auto_ptr(auto_ptr<T>& ap)
{
_ptr = ap._ptr;
ap._ptr = nullptr;
}
~auto_ptr()
{
delete _ptr;
}
T* operator->()
{
return _ptr;
}
T& operator*()
{
return *_ptr;
}
private:
T* _ptr;
};
}
shared_ptr
简介
利用引用计数来控制资源的释放
代码实现
先来看一下源码中的声明
cpp
template <class U, class D> shared_ptr (U* p, D del);
template <class D> shared_ptr (nullptr_t p, D del);
我们可能会有遇到在释放资源时,会遇到多种类型:单个、数组等,我们就需要定制适合我们的删除方式
这个del就是定制删除器
如果我们要传定制删除器,我们最好用成员来传递,也就是在构造函数中加一个参数del
cpp
shared_ptr(T* ptr, D del)
:_ptr = ptr
,_pcount(new int(1))
,_del(del)
{}
而要用成员来传递,需要先创建这个成员
cpp
D del;
而这个D,我们又需要在类的模板中加入这个参数,但源码中创建shared_ptr 的时候可没有这个参数,他只有一个参数
cpp
template <class T> class shared_ptr;
那我们要怎么办呢?再封装一层吗?太麻烦了
这里我们就可以使用新学的function包装器了,因为我们确定返回值(void)和封装方式(自己传参)的
cpp
function<void(T*)> _del;//创建的成员
//删除的时候release函数中就不是写死的了
//直接这样写即可
_del(_ptr);
还有个小问题:
对于不传删除器的调用,删除器为空,编译器报错。
我们可以直接给_del缺省值:
cpp
[](T* _ptr){delete _ptr;}
完整代码:
cpp
#include<functional>
using namespace std;
namespace memory
{
template<typename T>
class shared_ptr
{
public:
templae<class D>
shared_ptr(T* ptr, D del)
:_ptr(ptr)
,_pcount(new int(1))
,_del(del)
{}//构造
shared_ptr(shared_ptr<T>& sp)
{
if (sp._ptr != _ptr)
//防止直接或间接的给自己拷贝
{
_ptr = sp._ptr;
*_pcount++;
}
}
shared_ptr<T>& operator=(const shared_ptr<T>& sp)
{
release();
if (_ptr != sp._ptr)
{
_ptr = sp._ptr;
_pcount = sp.count;
++(*pcount);
}
return *this;
}
void release()
{
if (--(*_pcount) == 0)
{
_del(_ptr);
delete _pcount;
}
else
{
*_pcount--;
}
}
~shared_ptr()
{
release();
}
T* opertaor->()
{
return _ptr;
}
T& operator*()
{
return *_ptr;
}
int ues_count()
{
return *(_pcount);
}
private:
T* _ptr;
//每实例化一个对象,就产生一个指向count的指针
int* _pcount;
//定制删除器
function<void(T*)>_del = [](T*) {delete _ptr; };
};
}
weak_ptr
也是RAII,但不参与引用计数,
也就是没有_pcount,其他部分一样
结语
对于这三个指针的模拟实现到这里就结束了,
不过好像unique_ptr用的更多一些?