一. unique_ptr的基本用法

(一)初始化方式

  1. 直接初始化:unique<T> myPtr(new T);  //ok。但不能通过隐式转换来构造,如unique<T> myPtr = new T()。因为unique_ptr构造函数被声明为explicit

  2. 移动构造:unique<T> myOtherPtr = std::move(myPtr);但不允许复制构造,如unique<T> myOther = myPtr; 因为unique是个只移动类型。

  3. 通过make_unique构造:unique<T> myPtr = std::make_unique<T>(); //C++14支持的语法。但是make_都不支持添加删除器,或者初始化列表

  4. 通过reset重置:如std::unique_ptr up; up.reset(new T());

(二)指定删除器

  1. unique_ptr<T,D>  u1(p,d);删除器是unique_ptr类型的组成部分,可是普通函数指针或lambda表达式。注意,当指定删除器时需要同时指定其类型,即D不可省略。

  2.使用默认的deleter时,unique_ptr对象和原始指针的大小是一样的。当自定义deleter时,如果deleter是函数指针,则unique_ptr对象的大小为8字节。对于函数对象的deleter,unique_ptr对象的大小依赖于存储状态的多少,无状态的函数对象(如不捕获变量的lambda表达式),其大小为4字节

二. 剖析unique_ptr

(一)源码分析【节选】

//指向单对象
template <class _Ty, class _Dx> //注意,删除器也是unique_ptr类型的一部分
class unique_ptr { // non-copyable pointer to an object
private:
    _Compressed_pair<_Dx, pointer> _Mypair;
public:

    using pointer      = _Ty*;//裸指针类型
    using element_type = _Ty; //对象类型
    using deleter_type = _Dx; //删除器类型

    template <class _Dx2 = _Dx, _Unique_ptr_enable_default_t<_Dx2> = 0>
    constexpr unique_ptr() noexcept : _Mypair(_Zero_then_variadic_args_t()) {} //构造一个空的智能指针

    unique_ptr& operator=(nullptr_t) noexcept; //重置指针为nullptr

    //注意,explicit阻止隐式构造,如unique_ptr<int> up = new int(100);编译错误。只能显示构造,如unique_ptr<int> up(new int(100));
    template <class _Dx2 = _Dx, _Unique_ptr_enable_default_t<_Dx2> = 0>
    explicit unique_ptr(pointer _Ptr) noexcept : _Mypair(_Zero_then_variadic_args_t(), _Ptr) {} 

    template <class _Dx2 = _Dx, enable_if_t<is_constructible_v<_Dx2, const _Dx2&>, int> = 0>
    unique_ptr(pointer _Ptr, const _Dx& _Dt) noexcept : _Mypair(_One_then_variadic_args_t(), _Dt, _Ptr) {}

    unique_ptr(unique_ptr&& _Right) noexcept;  //移动构造

    unique_ptr& operator=(unique_ptr&& _Right) noexcept;//移动赋值

    void swap(unique_ptr& _Right) noexcept;//交换两个智能指针所指向的对象

    ~unique_ptr() noexcept; //析构函数,调用删除器释放资源。

    Dx& get_deleter() noexcept; //返回删除器

    const _Dx& get_deleter() const noexcept;//返回删除器

    add_lvalue_reference_t<_Ty> operator*() const; //解引用

    pointer operator->() const noexcept; //智能指针->运算符

    pointer get() const noexcept; 

    explicit operator bool() const noexcept; //类型转换函数,用于条件语句,如if(uniptr)之类

    pointer release() noexcept; //返回裸指针,并释放所有权

    void reset(pointer _Ptr = pointer()) noexcept ; //重置指针

    unique_ptr(const unique_ptr&) = delete; //不可拷贝
    unique_ptr& operator=(const unique_ptr&) = delete; //不可拷贝赋值
};

//指向数组类型
template <class _Ty, class _Dx>
class unique_ptr<_Ty[], _Dx> { 
private:
    _Compressed_pair<_Dx, pointer> _Mypair; 
public:
    using pointer      = typename _Get_deleter_pointer_type<_Ty, remove_reference_t<_Dx>>::type;
    using element_type = _Ty;
    using deleter_type = _Dx;

    //...    //省略了与unique_ptr单对象类型相同的一些操作
   
    ~unique_ptr() noexcept; //析构函数,调用删除器释放资源。

    _Ty& operator[](size_t _Idx) const {  //数组[]操作符
        return _Mypair._Myval2[_Idx];
    }

    unique_ptr(const unique_ptr&) = delete;
    unique_ptr& operator=(const unique_ptr&) = delete;
};
unique_ptr

相关文章:

  • 2021-07-09
  • 2022-12-23
  • 2021-04-18
  • 2021-07-16
  • 2021-10-22
  • 2022-12-23
  • 2022-12-23
  • 2021-12-18
猜你喜欢
  • 2021-12-06
  • 2021-12-30
  • 2018-04-30
  • 2022-12-23
  • 2022-12-23
  • 2022-01-27
相关资源
相似解决方案