定义
对于智能指针unique_ptr有两种定义方式
第一种,管理单个对象(使用new分配),并使用默认的删除器。
template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
第二种则是管理对象数组(使用new[] 分配),并且需要用户指定删除器。Deleter 必须是函数对象
template <
class T,
class Deleter
> class unique_ptr<T[], Deleter>;
对于unique_ptr 满足可移动构造,可移动赋值,可复制赋值与可赋值构造则定义为删除形式。
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
描述
一个unique_ptr能将所有权给另一个unique_ptr,不能将const的unique_ptr给另一个unique_ptr.
unique_ptr可以保存到vector容器中。
关于继承,若 T
是某基类 B
的派生类,则 std::unique_ptr<T> 可隐式转换为 std::unique_ptr<B>。产生的 std::unique_ptr<B> 的默认删除器将使用 基类B
的 opterator delete ,因此会出现未定义行为错误,除非 B
的析构函数为虚函数。
std::shared_ptr不会出现此问题。std::shared_ptr<B> 将使用类型 T
的 派生类的opterator delete 函数 ,而且即使 基类B
的析构函数非虚函数,也会正确删除对象。
关联的函数
1.构造函数
构造函数有很多种,只列举移动构造,但是赋值构造默认是删除的。
unique_ptr(unique_ptr&& __u) noexcept
: _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
2.析构函数
~unique_ptr()
{
auto& __ptr = _M_t._M_ptr();
if (__ptr != nullptr)
get_deleter()(__ptr);
__ptr = pointer();
}
3.赋值函数
所谓的赋值函数是可移动赋值函数,不是拷贝赋值函数,
unique_ptr&
operator=(unique_ptr&& __u) noexcept
{
reset(__u.release());
get_deleter() = std::forward<deleter_type>(__u.get_deleter());
return *this;
}
4.release函数
释放存储的指针,但不释放指针指向的对象,返回释放的指针。
如果调用release后没有接收此指针,则数据指向的数据将不会被释放。
pointer
release() noexcept
{
pointer __p = get();
_M_t._M_ptr() = pointer();
return __p;
}
5.reset函数
重新接收新的指针,如果当前指针和传入指针不是同一个,则调用删除器释放当前指针指向的数据 。
保留的是传入的新指针。
reset(pointer __p = pointer()) noexcept
{
using std::swap;
swap(_M_t._M_ptr(), __p);
if (__p != pointer())
get_deleter()(__p);
}
6.swap函数
使用std::swap函数
void
swap(unique_ptr& __u) noexcept
{
using std::swap;
swap(_M_t, __u._M_t);
}
7.get函数
返回存储的指针
pointer
get() const noexcept
{ return _M_t._M_ptr(); }
8.get_deleter函数
返回对象对应的删除器
deleter_type&
get_deleter() noexcept
{ return _M_t._M_deleter(); }
_M_t是tuple类型。
_Dp& _M_deleter() { return std::get<1>(_M_t); }
取tuple的第二个元素,也就是std::get<1>(tuple);
返回当前存储的指针是不是空,是空的话返回false, 非空返回ture
explicit operator bool() const noexcept
{ return get() == pointer() ? false : true; }
对存储的指针进行解引用操作
typename add_lvalue_reference<element_type>::type
operator*() const
{
__glibcxx_assert(get() != pointer());
return *get();
}
返回存储的对象指针。
pointer
operator->() const noexcept
{
_GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
return get();
}
主要实现:
typename std::add_lvalue_reference<element_type>::type
operator[](size_t __i) const
{
__glibcxx_assert(get() != pointer());
return get()[__i];
}
get()函数会返回当前数组的指针。
pointer get() const noexcept { return _M_t._M_ptr(); }
_M_t的类型时std::tuple类型,tuple中第一个元素是对象指针,第二个对象是删除器。
pointer _M_ptr() const { return std::get<0>(_M_t); }
_M_ptr()是取tuple中的第一个元素,对象指针。