简介
unique_ptr
是 C++ 11 提供的用于防止内存泄漏的智能指针中的一种实现,独享被管理对象指针所有权的智能指针。unique_ptr对象包装一个原始指针,并负责其生命周期。当该对象被销毁时,会在其析构函数中删除关联的原始指针。
unique_ptr
对象始终是关联的原始指针的唯一所有者,我们无法复制unique_ptr
对象,它只能移动。
首先我们利用STL提供的unique_ptr
管理对象时,不能完成下面框出的操作:
上述操作受限与否的原理是什么?和之前一样,我们模仿源码的逻辑,仿写unique_ptr,看看unique_ptr
的实现原理:
先来实现一下unqiue_ptr
的默认删除器
由于每个unique_ptr
对象都是原始指针的唯一所有者,因此在其析构函数中它直接删除关联的指针,不需要任何参考计数。
//泛化模板类
template<class _Ty>
class Mydeletor
{
Mydeletor() = default;
void operator()(_Ty *ptr)const
{
if(ptr != nullptr)
{
delete ptr;
}
}
};
//部分特化
template<class _Ty>
class Mydeletor<_Ty[]>
{
Mydeletor() = default;
void operator()(_Ty *ptr)const
{
if(ptr != nullptr)
{
delete[] ptr;
}
}
};
继续完成unqiue_ptr
的设计
template<class _Ty,class _Dx = Mydeletor<_Ty>>//给出一个删除单个对象的删除器
class my_unique_ptr
{
//C11新写法
using pointer = _Ty*; // typedef _Ty pointer;
using element_type = _Ty;// typedef _Ty element_type;
using delete_type = _Dx; // typedef _Dx delete_type;
private:
_Ty* _Ptr;
_Dx _myDeletor;
public:
my_unique_ptr(const my_unique_ptr &) = delete;
my_unique_ptr & operator=(const my_unique_ptr &) = delete;
my_unique_ptr(pointer _p = nullptr):_Ptr(_p){}
~my_unique_ptr()
{
if(_Ptr != nullptr)
{
_myDeletor(_Ptr);//对象()——>调动仿函数
_Ptr = nullptr;
}
}
//移动构造
my_unique_ptr(my_unique_ptr && _Y)
{
_Ptr = _Y._Ptr;
_Y._Ptr = nullptr;
}
//移动赋值
my_unique_ptr & operator=(my_unique_ptr && _Y)
{
if(this == &_Y)return *this;
reset(_Y.release());
//if(_Ptr != nullptr)
//{
// _myDeletor(_Ptr);
//}
//_Ptr = _Y._Ptr;
//_Y._Ptr = nullptr;
return *this;
}
//返回删除器对象
_Dx & get_deletor()
{
return _myDeletor;
}
const _Dx & get_deletor() const
{
return _myDeletor;
}
//解引用指向被管理对象的指针
_Ty & operator*()const
{
return *_Ptr;
}
pointer operator->()const
{
return _Ptr;//&**this
}
//返回指向管理对象的指针
pointer get() const
{
return _Ptr;
}
//测试当前_Ptr指向是否为nullptr
operator bool() const//强转bool
{
return _Ptr != nullptr;
}
//my_unqiue_ptr<int> op;
//if(op){}//——>if(op.operator bool()){}
pointer release()
{
_Ty *old = _Ptr;
_Ptr = nullptr;
return old;
}
void reset(pointer _P = nullptr)
{
pointer old = _Ptr;
_Ptr = _P;
if(old != nullptr)
{
_myDeletor(old);//get_deletor(old);
}
}
void Swap(my_unique_ptr _Y)
{
std::swap(_Ptr,_Y.Ptr);
std::swap(_myDeletor,_Y._myDeletor);
}
};
//部分特化:处理数组
class my_unique_ptr<_Ty[],_Dx>
{
//C11新写法
using pointer = _Ty*; // typedef _Ty pointer;
using element_type = _Ty;// typedef _Ty element_type;
using delete_type = _Dx; // typedef _Dx delete_type;
private:
_Ty* _Ptr;
_Dx _myDeletor;
public:
my_unique_ptr(const my_unique_ptr &) = delete;
my_unique_ptr & operator=(const my_unique_ptr &) = delete;
my_unique_ptr(pointer _p = nullptr):_Ptr(_p){}
~my_unique_ptr()
{
if(_Ptr != nullptr)
{
_myDeletor(_Ptr);//对象()——>调动仿函数
_Ptr = nullptr;
}
}
//移动构造
my_unique_ptr(my_unique_ptr && _Y)
{
_Ptr = _Y._Ptr;
_Y._Ptr = nullptr;
}
//移动赋值
my_unique_ptr & operator=(my_unique_ptr && _Y)
{
if(this == &_Y)return *this;
reset(_Y.release());
//if(_Ptr != nullptr)
//{
// _myDeletor(_Ptr);
//}
//_Ptr = _Y._Ptr;
//_Y._Ptr = nullptr;
return *this;
}
//返回删除器对象
_Dx & get_deletor()
{
return _myDeletor;
}
const _Dx & get_deletor() const
{
return _myDeletor;
}
//解引用指向被管理对象的指针
_Ty & operator*()const
{
return *_Ptr;
}
pointer operator->()const
{
return _Ptr;//&**this
}
//返回指向管理对象的指针
pointer get() const
{
return _Ptr;
}
//检查是否有关联的被管理对象
operator bool() const//强转bool
{
return _Ptr != nullptr;
}
//my_unqiue_ptr<int> op;
//if(op){}//——>if(op.operator bool()){}
pointer release()
{
_Ty *old = _Ptr;
_Ptr = nullptr;
return old;
}
void reset(pointer _P = nullptr)
{
pointer old = _Ptr;
_Ptr = _P;
if(old != nullptr)
{
_myDeletor(old);//get_deletor(old);
}
}
void Swap(my_unique_ptr _Y)
{
std::swap(_Ptr,_Y.Ptr);
std::swap(_myDeletor,_Y._myDeletor);
}
_Ty & operator[](size_t _Idx) const
{
return _Ptr[_Idx];
}
};
template<class _Ty,class ... _Type>//可变参
my_unique_ptr<_Ty> my_make_unique(_Type&& ... arys)
{
return my_unique_ptr<_Ty>(new _Ty(_arys...));
}
unique_ptr具有->
和*
运算符重载符,因此它可以像普通指针一样使用。
关于unique_ptr的使用,可以参考这一篇博客:
C++ 智能指针 unique_ptr 详解与示例