C++11智能指针--unique_ptr

C++11依据使用场景的不同创建了两个新的智能指针:unique_ptr和shared_ptr、weak_ptr。

一、unique_ptr分析和使用

        unique_ptr:是“独占”对象所有权语义的智能指针。

        unique_ptr实现了独享被管理对象指针的概念,这意味着它可确保一个对象和其对应的资源同一时间只能被一个unique_ptr对象拥有。一旦拥有者被销毁或者变成empty或者开始拥有另一个对象的地址,先前拥有的那个对象就会被销毁,其任何相应资源也会被释放。

1、特点:

基于排他所有权模式:两个指针不能指向同一个资源。

由于独占对象的所有权,所以不提供拷贝构造函数和赋值函数重载。

提供移动构造和移动赋值函数。

为了实现单个对象和一组对象的管理,添加了删除器类型。

2、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;//一组对象
    }
};

template<class _Ty,class _Dx=default_deleter<_Ty> >
class unique_ptr
{
public:
    using pointer=_Ty*;
    using element_tyoe=_Ty;
    using deleter_type=_Dx;
private:
    pointer mPtr;
    deleter_type=_Dx;
public:
    unique_ptr(pointer p=nullptr):mPtr(p) { }
    unique_ptr(const unique_ptr&)=delete;//删除拷贝构造
    unique_ptr& operator=(const unique_ptr&)=delete;//删除赋值重载函数
    ~unique_ptr()
    {
        if(mPtr!=nullptr)
            reset();
    }
    
    //移动构造函数
    template<class _Ty2,class _Dx2>
    unique_ptr(unique_ptr<_Ty2,_Dx2>&& other)
    {
        reset(other.release());
    }
    //移动赋值函数
    template<class _Ty2,class _Dx2>
    unique_ptr& operator=(unique_ptr<_Ty2,_Dx2>&& other)
    {
        if(this!=(unique_ptr<_Ty,_Dx>*)&other)
        {
            reset(other.release());
        }
        return *this;
    }
    
    //释放被管理对象的所有权
    pointer release()
    {
        pointer old=mPtr;
        mPtr=nullptr;
        return old;
    }
    void reset(pointer ptr=nullptr)
    {
        if(mPtr!=nullptr)
        {
            mDeleter(mPtr);
        }
        mPtr=ptr;
    }
    void swap(unique_ptr& other)
    {
        std::swap(this->mPtr,other.mPtr);
    }
    pointer get()const
    {
        return mPtr;
    }
    
    //返回用于析构被管理对象的删除器
    _Dx& get_deleter()
    {
        return m_Deleter;
    }
    const _Dx& get_deleter()const
    {
        return m_Deleter;    
    }
    explicit operator bool()const
    {
        return static_cast<bool>(mPtr!=nullptr);
    }
    _Ty& operator*()const
    {
        return *mPtr;
    }
    pointer operator->()const
    {
        return get();
    }
  
};

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 p=nullptr):mPtr(p)
    { }
    unique_ptr(const unique_ptr&)=delete;
    unique_ptr& operator=(const unqiue_ptr&)=delete;
    
    //移动构造
    template<class _Ty2,class _Dx2>
    unique_ptr(unique_ptr<_Ty,_Dx2>&& other)
    {
        if(this!=(unique_ptr<_Ty,_Dx>*>& other)
        {
            reset(other.release());
        }
    }       
    //移动赋值
    template<class _Ty2,class _Dx2>
    unique_ptr& operator=(unique_ptr<_Ty2,_Dx2>&& other)
    {
        if(this!=(unique_ptr<_Ty,_Dx>*)& other)
        {
            reset(other.release());
        }
        return *this;
    }
    ~unique_ptr()
    {
        if(mPtr!=nullptr)
            reset();
    }
    //释放被管理对象的所有权
    pointer release()
    {
        pointer old=mPtr;
        mPtr=nullptr;
        return old;
    }
    void reset(pointer ptr=nullptr)
    {
        if(mPtr!=nullptr)
            mDeleter(mPtr);
        mPtr=ptr;
    }
    void swap(unique_ptr& other)
    {
        std::swap(this->mPtr,other.mPtr);
    }
    pointer get()const
    {
        return mPtr;
    }
    //返回用于析构被管理对象的删除器
    _Dx& get_deleter()
    {
        return mDeleter;
    }
    const _Dx& get_deleter()const
    {
        return mDeleter;
    }
    explicit operator bool()const
    {
        return static_cast<bool>(mPtr!=nullptr);
    }
    _Ty& operator*()const
    {
        return *mPtr;
    }
    pointer operator->()const
    {
        return get();
    }
    _Ty& operator[](std::size_t i)const
    {
        return get()[i];//mPtr[i]
    }
};

3、辅助函数

(1)get返回指向被管理对象的指针;

(2)reset替换被管理对象;

(3)release释放被管理对象的所有权;

(4)swap交换被管理对象;

(5)operator[] bool() const检查是否有关联的被管理对象;

(6)重载operator*,operator->,访问被管理对象。

4、不能拷贝构造和左值赋值

5、可以移动构造和移动赋值

6、管理动态数组

7、使用unique_ptr总结

        unique_ptr在要表达“专属所有权”的语义时使用,即unique_ptr指针永远拥有其指向的对象,所以unique_ptr是一个move_only类型,一个unique_ptr指针是无法被复制的,只能将所有权在两个unique_ptr指针之间转移,转移完成后原来的unque_ptr将被设为nullptr。

(1)语义简单,即当你确定要使用的指针是不是被共享所有权的时候,认选unique_ptr独占式所有权,当确定要被共享的时候可以转换成shared_ptr;

(2)unique_ptr效率比shared_ptr高,不需要维护引用计数块;

(3)在需要时可以将unique_ptr转换成shared_ptr。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值