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. 对比

相关推荐
程与留13 小时前
15_国际化和本地化:tr()、ts 文件、QM 文件、多语言切换
c++·qt
程与留15 小时前
14_Qt 样式表(QSS)入门(语法、选择器、美化实战)
c++·qt
欧特克_Glodon1 天前
OpenCV计算机视觉开发入门与实践<二十七>:图像分割概述
c++·人工智能·opencv·计算机视觉
蒸蒸yyyyzwd1 天前
cpp 选手秋招学习笔记 day21
c++·面试·八股
「QT(C++)开发工程师」1 天前
C++ auto 用法详解
开发语言·c++
OPEN-F1 天前
C++STL教程:容器适配器与实用工具
开发语言·c++
OPEN-F1 天前
C++模板教程:变参模板、折叠表达式与SFINAE
java·开发语言·c++
有点。1 天前
C++二叉搜索树进阶
开发语言·c++
HugoStudio_SWAN1 天前
【擦除重绘】C++ 控制台动画:弹跳 Logo DVD 屏保效果
开发语言·c++·学习·程序人生
kyle~2 天前
C++_STL---迭代器失效
开发语言·c++