手撕简易版的智能指针

目录

一、智能指针的通用模板

二、auto_ptr(禁止使用)

三、unique_ptr

四、shared_ptr

五、定制删除器(shared_ptr))


一、智能指针的通用模板

对于智能指针一般需实现构造、*、->、析构等函数,私有成员包括未定义类型的指针,至于拷贝构造和赋值重载按需实现。

cpp 复制代码
/*
    template<class T>
    class smartptr
    {
    public:
        smartptr(T*ptr):_ptr(ptr){}
        ~smartptr(){if(_ptr) delete _ptr;}
        T*operator->() { return _ptr; }
        T&operator*() { return *_ptr;}
        //拷贝构造和赋值构造......
    private:
        T*_ptr;
    };
    */

二、auto_ptr(禁止使用)

对于auto_ptr(关键实现管理权限的转移)仅供学习,禁止使用

注:

(1)权限的转移,所以构造赋值传参不能加const

(2)赋值重载时,

//1.自己=自己,直接返回自己本身

//2.自己=other,other先改变(释放)原指针的管理,在挂接到新的指针上

cpp 复制代码
template<class T>
    //权限的转移,所以构造赋值传参不能加const
    class auto_ptr
    {
    public:
        //无参与有参构造
        auto_ptr(T*ptr = nullptr) { _ptr = ptr; }
        T*operator->(){return _ptr;}
        T&operator*(){return *_ptr;}
        //拷贝构造
        auto_ptr(auto_ptr<T>&sp)
        {
            _ptr = sp._ptr;
            sp._ptr = nullptr;
        }
        void release()
        {
            if(_ptr)
                delete _ptr;
        }
        //赋值构造
        auto_ptr&operator=(auto_ptr<T>&sp)
        {
            //1.自己=自己,直接返回自己本身
            //2.自己=other,other先改变(释放)原指针的管理,在挂接到新的指针上
            if(_ptr != sp._ptr)
            {
                release();
                _ptr = sp._ptr;
                sp._ptr = nullptr;
            }
            return *this;
        }

        ~auto_ptr()
        {
            release();
        }
    private:
        T *_ptr;
    };

三、unique_ptr

主要是禁止拷贝构造和赋值重载

cpp 复制代码
template<class T>
    //禁止拷贝和赋值
    class unique_ptr
    {
    public:
        unique_ptr(T* ptr = nullptr) : _ptr(ptr) {}
        T*operator->() { return _ptr; }
        T&operator*() { return *_ptr;}
        ~unique_ptr()
        {
            if(_ptr) 
                delete _ptr;
        }
        T* get() const { return _ptr; }
        unique_ptr(const unique_ptr<T>&sp) = delete;
        unique_ptr&operator=(const unique_ptr<T>&sp) = delete;
    private:
        T *_ptr;
    };

四、shared_ptr

采用引用计数的方式进行智能指针的管理

注:

(1)//计数方式:
/*1.在堆上开辟一块空间进行计数的维护(make_shared的原理)
2.直接使用int私有成员,表示每一个对象一个计数这样就不合理
3.使用静态成员的话,所有类成员均可见,换一个对象再计数也不合理*/

(2)赋值重载和auto_ptr那相同注意点

cpp 复制代码
// //未加定制删除器
    // class shared_ptr
    // {
    // public:
    //     shared_ptr(T*ptr = nullptr) : _ptr(ptr), _count(new int(1)) {}
    //     shared_ptr(const shared_ptr<T>&sp)
    //     {
    //         _ptr = sp._ptr;
    //         _count = sp._count;
    //         (*_count)++;
    //     }
    //     void release()
    //     {
    //         if(--(*_count) == 0)
    //         {
    //             delete _ptr;
    //             delete _count;
    //         }
    //     }
    //     //1.自己=自己,直接返回自己本身
    //         //2.自己=other,自己先改变(释放)原指针的管理,在挂接到新的指针上
    //     shared_ptr&operator=(const shared_ptr<T>&sp)
    //     {
    //         if(_ptr != sp._ptr)
    //         {
    //             release();
    //             _ptr = sp._ptr;
    //             _count = sp._count;
    //             (*_count)++;
    //         }
    //         return *this;
    //     }
    //     ~shared_ptr()
    //     {
    //         release();
    //     }
    //     T*operator->() {return _ptr;}
    //     T&operator*() {return *_ptr;}
    //     int use_count() {return *_count;}
    //     T*get()const {return _ptr;}
    // private:
    //     T *_ptr;
    //     int *_count;
    // };

五、定制删除器(shared_ptr)

(特殊的函数类型传入相应的析构函数),完成正确的析构,避免内存泄漏

c++标准库引入定制删除器的方式:

//unique_ptr添加定制删除器是实例化模板添加,

unique_ptr<Date[ ]> / unique_ptr<Date[ ],delete[ ]>
//shared_ptr是函数构造时添加的表达式或者仿函数

shared_ptr<FILE> sp(fopen("text.cc),fclose(lambda表达式,函数指针,仿函数等))
仅简单手撕shared_ptr版本

注:

//若我们直接引入模板进行构造添加,eg:
/*template<class D>
shared_ptr(T*ptr,D del){}*/
//构造析构时无法实例化(类型)和传参lambda表达式和仿函数
//所以引入包装器function,可以对所有的lambda表达式和仿函数进行包装,不用考虑类型
//包装器传入后,对象析构时会调用对象对应的析构(删除器)如果没传的话会内存泄漏,因此我们要有默认形式:
//function<void(T*ptr)> _del = [](T*ptr){delete ptr;};

cpp 复制代码
class shared_ptr
    {
    public:
        shared_ptr(T*ptr = nullptr) : _ptr(ptr), _count(new int(1)) {}
        //定制删除器构造
        template<class D>
        shared_ptr(T*ptr,D del) : _ptr(ptr), _count(new int(1)),_del(del) {}
        shared_ptr(const shared_ptr<T>&sp)
        {
            _ptr = sp._ptr;
            _count = sp._count;
            (*_count)++;
        }
        void release()
        {
            if(--(*_count) == 0)
            {
                // delete _ptr;
                _del(_ptr);
                delete _count;
            }
        }
        //1.自己=自己,直接返回自己本身
            //2.自己=other,自己先改变(释放)原指针的管理,在挂接到新的指针上
        shared_ptr&operator=(const shared_ptr<T>&sp)
        {
            if(_ptr != sp._ptr)
            {
                release();
                _ptr = sp._ptr;
                _count = sp._count;
                (*_count)++;
            }
            return *this;
        }
        ~shared_ptr()
        {
            release();
        }
        T*operator->() {return _ptr;}
        T&operator*() {return *_ptr;}
        int use_count() {return *_count;}
        T*get()const {return _ptr;}
    private:
        T *_ptr;
        int *_count;
        function<void(T*ptr)> _del = [](T*ptr){delete ptr;};
    };
相关推荐
rainbow68891 小时前
Linux文件描述符与重定向原理
c++
CodeSheep程序羊1 小时前
拼多多春节加班工资曝光,没几个敢给这个数的。
java·c语言·开发语言·c++·python·程序人生·职场和发展
编程小白20262 小时前
从 C++ 基础到效率翻倍:Qt 开发环境搭建与Windows 神级快捷键指南
开发语言·c++·windows·qt·学习
.小墨迹2 小时前
apollo学习之借道超车的速度规划
linux·c++·学习·算法·ubuntu
历程里程碑3 小时前
Linux20 : IO
linux·c语言·开发语言·数据结构·c++·算法
郝学胜-神的一滴3 小时前
深入浅出:使用Linux系统函数构建高性能TCP服务器
linux·服务器·开发语言·网络·c++·tcp/ip·程序人生
天若有情6733 小时前
【自研实战】轻量级ASCII字符串加密算法:从设计到落地(防查岗神器版)
网络·c++·算法·安全·数据安全·加密
czy87874754 小时前
深入了解 C++ 中的 `std::bind` 函数
开发语言·c++
我在人间贩卖青春4 小时前
C++之继承的方式
c++·private·public·protected·继承方式
智者知已应修善业5 小时前
【洛谷P9975奶牛被病毒传染最少数量推导,导出多样例】2025-2-26
c语言·c++·经验分享·笔记·算法·推荐算法