0. 引言
上一篇文章介绍了auto_ptr,由于auto_ptr存在着诸多问题,C++11引入了三个新的智能指针unique_ptr、shared_ptr和weak_ptr,本文介绍unique_ptr。
1. unique_ptr的特点
unique_ptr实现了独享被管理资源指针的概念,顾名思义,它确保了一个unique_ptr对象与一个资源的唯一对应。unique_ptr有以下一些特点:
- 两个unique_ptr不会指向同一个资源;
- unique_ptr类型不提供拷贝构造函数和左值赋值函数重载;
- 但提供移动构造函数和移动赋值函数;
- 相对于auto_ptr,unique_ptr添加了删除器类型;
- 可以与STL中的容器配合使用;
- 在用法上和普通指针的用法类似,也提供了*和->运算符。
2. unique_ptr的分析
下面的代码对unique_ptr类型进行了简单仿写,展示了unique_ptr的使用特点。
//删除器仿写,处理单个对象
template<class _Ty>
struct default_deleter
{
void operator()(_Ty* ptr) const
{
delete ptr; //删除单个对象
}
};
//处理一组对象
template<class _Ty>
struct default_deleter<_Ty[]>
{
void operator()(_Ty* ptr) const
{
delete[]ptr; //删除一组对象
}
};
//unique_ptr的泛化版本,该模板只能处理单个对象
template<class _Ty, class _Dx = default_deleter<_Ty>>
class unique_ptr
{
public:
using pointer = _Ty*;
using element_type = _Ty;
using deleter_type = _Dx;
private:
pointer mPtr;
deleter_type mDeleter;
public:
unique_ptr(pointer ptr = nullptr) :mPtr(ptr) {}
~unique_ptr()
{
reset();
}
//返回删除器对象
_Dx& get_deleter() const
{
return mDeleter;
}
const _Dx& get_deleter() const
{
return mDeleter;
}
//替换被管理对象
void reset(pointer ptr = nullptr)
{
if (mPtr != nullptr)
{
mDeleter(mPtr);
}
mPtr = ptr;
}
};
//unique_ptr部分特化版本,该版本处理一组对象
template<class _Ty, class _Dx>
class unique_ptr<_Ty[], _Dx>
{
public:
using pointer = _Ty*;
using element_type = _Ty;
using deleter_type = _Dx;
private:
pointer mPtr;
deleter_type mDeleter;
public:
unique_ptr(pointer ptr = nullptr) :mPtr(ptr) {}
~unique_ptr()
{
reset();
}
void reset(pointer ptr = nullptr)
{
if (mPtr != nullptr)
{
mDeleter(mPtr);
}
mPtr = ptr;
}
_Dx& get_deleter()
{
return mDeleter;
}
const _Dx& get_deleter() const
{
return mDeleter;
}
element_type& operator*() const = delete;
pointer operator->() const = delete;
pointer get() const
{
return mPtr;
}
element_type& operator[](size_t i) const
{
return get()[i];
}
};
3. unique_ptr的总结
总的来说,unique_ptr就是一个添加了删除器的auto_ptr,用于管理一组对象,并引入了右值引用的概念。unique_ptr不允许拷贝构造和左值赋值,但提供了移动构造和移动赋值。