RAII 智能指针

1. RAII

  • RAII (Resource Acquisition Is Initialization)是一种利用对象生命周期 来控制程序资源(如内存、文件句柄、网络连接、互斥量等等)的简单技术。

  • 对象构造时获取资源 ,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个对象。这种做法有两大好处。

    • 不需要显式地释放资源。

    • 对象所需的资源在其生命期内始终保持有效。

  • 智能指针 是 RAII 在 C++ 中的具体实现,专门用于管理动态内存,提供更高级的功能(如所有权转移、引用计数等)。

  • 关系:智能指针是 RAII 的一种应用,而 RAII 是更广泛的设计思想。

2. 发展历史

  1. C++98 auto_ptr 管理权转移 ->不好的设计会出现对象悬空

  2. boost scoped_ptr 防拷贝->简单粗暴,对不需要拷贝的场景非常好。

  3. boost shared_ptr 引用计数 ,最后一个释放对象资源->复杂一些,但是支持拷贝,非常完美->问题:循环引用

  4. C++11 unique_ptr 防拷贝->简单粗暴,对不需要拷贝的场景非常好。

  5. C++11 shared_ptr 引用计数 ,最后一个释放对象资源->复杂一些,但是支持拷贝,非常完美->问题:循环引用

  6. C++11 weak_ptr 弱引用计数 ->仅观察对象,不影响对象生命周期->解决了循环引用( 如双向链表**)**。

3. auto_ptr

cpp 复制代码
// C++98
// 管理权转移,最后一个拷贝对象管理资源,被拷贝对象都被置空
// 很多公司都明确规定了,不要用这个
template<class T>
class auto_ptr
{
public:
        // RAII
        auto_ptr(T* ptr)
                :_ptr(ptr)
        {}
        ~auto_ptr()
        {
                if (_ptr)
                {
                        cout << "delete->" << _ptr << endl;
                        delete _ptr;
                        _ptr = nullptr;
                }
        }
        // ap2(ap1)
        auto_ptr(auto_ptr<T>& ap)
                :_ptr(ap._ptr)
        {
                ap._ptr = nullptr;
        }
        T& operator*()
        {
                return *_ptr;
        }
        T* operator->()
        {
                return _ptr;
        }
private:
        T* _ptr;
};

4. unique_ptr

cpp 复制代码
template<class T>
class unique_ptr
{
public:
        // RAII
        unique_ptr(T* ptr)
                :_ptr(ptr)
        {}
        ~unique_ptr()
        {
                cout << "delete->" << _ptr << endl;

                delete _ptr;
        }
        T& operator*()
        {
                return *_ptr;
        }

        T* operator->()
        {
                return _ptr;
        }
        // C++11
        unique_ptr(const unique_ptr<T>& up) = delete;
        unique_ptr<T>& operator=(const unique_ptr<T>& up) = delete;
private:
        // C++98
        // 1、只声明不实现
        // 2、限定为私有
        //unique_ptr(const unique_ptr<T>& up);
        //unique_ptr<T>& operator=(const unique_ptr<T>& up);
private:
        T* _ptr;
};

5. shared_ptr

cpp 复制代码
template<class T>
class shared_ptr
{
public:
        // RAII
        shared_ptr(T* ptr = nullptr)
                :_ptr(ptr)
                , _pcount(new int(1))
        {}
        template<class D>
        shared_ptr(T* ptr, D del)
                : _ptr(ptr)
                , _pcount(new int(1))
                , _del(del)
        {}
        // function<void(T*)> _del;
        void release()
        {
                if (--(*_pcount) == 0)
                {
                        //cout << "delete->" << _ptr << endl;
                        //delete _ptr;
                        _del(_ptr);

                        delete _pcount;
                }
        }
        ~shared_ptr()
        {
                release();
        }
        shared_ptr(const shared_ptr<T>& sp)
                :_ptr(sp._ptr)
                , _pcount(sp._pcount)
        {
                ++(*_pcount);
        }
        // sp1 = sp3
        shared_ptr<T>& operator=(const shared_ptr<T>& sp)
        {
                if (_ptr != sp._ptr)
                {
                        release();
                        _ptr = sp._ptr;
                        _pcount = sp._pcount;

                        ++(*_pcount);
                }
                return *this;
        }
        T& operator*()
        {
                return *_ptr;
        }
        T* operator->()
        {
                return _ptr;
        }
        int use_count() const
        {
                return *_pcount;
        }
        T* get() const
        {
                return _ptr;
        }
private:
        T* _ptr;
        int* _pcount;
        function<void(T*)> _del = [](T* ptr) {delete ptr; };
};

6. weak_ptr

cpp 复制代码
template<class T>
class weak_ptr
{
public:
        weak_ptr()
                :_ptr(nullptr)
        {}
        weak_ptr(const shared_ptr<T>& sp)
                :_ptr(sp.get())
        {}
        weak_ptr<T>& operator=(const shared_ptr<T>& sp)
        {
                _ptr = sp.get();
                return *this;
        }
        T& operator*()
        {
                return *_ptr;
        }
        T* operator->()
        {
                return _ptr;
        }
private:
        T* _ptr;
};

7. 对比

相关推荐
王老师青少年编程16 分钟前
2025年3月GESP真题及题解(C++七级): 图上移动
c++·题解·dp·真题·gesp·七级·图上运动
编程大师哥17 分钟前
C++ 中解锁 Redis
开发语言·c++·redis
王老师青少年编程21 分钟前
2025年3月GESP真题及题解(C++七级): 等价消除
c++·编程·题解·真题·gesp·七级·等价消除
Yupureki24 分钟前
《算法竞赛从入门到国奖》算法基础:入门篇-贪心算法(上)
c语言·数据结构·c++·算法·贪心算法·visual studio
散峰而望26 分钟前
【算法竞赛】队列和 queue
开发语言·数据结构·c++·算法·链表·github·线性回归
yuanmenghao30 分钟前
车载Linux 系统问题定位方法论与实战系列 - 开篇: 为什么需要一套“系统化”的 Linux 问题定位方法
linux·运维·服务器·数据结构·c++·自动驾驶
一只小bit32 分钟前
Qt 对话框全方面详解,包含示例与解析
前端·c++·qt·cpp·页面
柏木乃一32 分钟前
基础IO(上)
linux·服务器·c语言·c++·shell
e***98571 小时前
C++跨平台开发的5大核心挑战与突破
开发语言·c++
橘颂TA1 小时前
【剑斩OFFER】算法的暴力美学——leetCode 662 题:二叉树最大宽度
c++·算法·结构与算法