IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++(18)——智能指针unique_ptr -> 正文阅读

[C++知识库]C++(18)——智能指针unique_ptr

简介

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 详解与示例

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:14:26  更:2022-03-12 17:17:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:18:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码