美文网首页
C++智能指针

C++智能指针

作者: LEO_青蛙 | 来源:发表于2022-02-11 12:04 被阅读0次

    智能指针其实本质是一个模板类,一般使用是用的这个类的对象,而不是指针
    智能指针体现在内存释放问题,用智能指针管理new的对象,不需要手动delete

    1、唯一指针std::unique_ptr<T>

    独占资源所有权的指针。
    (1)使用 std::unique_ptr 自动管理内存

    {
        std::unique_ptr<int> uptr = std::make_unique<int>(200);
        //...
        // 离开 uptr 的作用域的时候自动释放内存
    }
    

    (2)std::unique_ptr 是 move-only 的

    {
        std::unique_ptr<int> uptr = std::make_unique<int>(200);
        std::unique_ptr<int> uptr1 = uptr;  // 编译错误,std::unique_ptr<T> 是 move-only 的
    
        std::unique_ptr<int> uptr2 = std::move(uptr);
        assert(uptr == nullptr);
    }
    

    2、共享指针std::shared_ptr<T>

    共享资源所有权的指针。
    shared_ptr 需要维护的信息有两部分:
    (1)指向共享资源的指针
    (2)引用计数等共享资源的控制信息——实现上是维护一个指向控制信息的指针。
    简单实现共享指针

    template<typename T>
    class shared_ptr
    {
    private:
        T* _ptr;
        int* _count;//共享引用计数,必须使用指针
    public:
        //构造函数
        shared_ptr(T* ptr = nullptr) : _ptr(ptr)
        {
            if (_ptr)
            {
                _count = new int(1);
            }
            else
            {
                _count = new int(0);
            }
        }
    
        //拷贝构造
        shared_ptr(const shared_ptr& ptr)
        {
            if (this != &ptr)
            {
                this->_ptr = ptr._ptr;
                this->_count = ptr._count;
                //引用计数+1
                (*this->_count)++;
            }
        }
    
        //重载operator=
        shared_ptr& operator=(const shared_ptr& ptr)
        {
            if (this->_ptr == ptr._ptr)
            {
                return *this;
            }
            if (this->_ptr)
            {
                (*this->_count)--;
                if (*this->_count == 0)
                {
                    delete this->_ptr;
                    delete this->_count;
                }
            }
            this->_ptr = ptr._ptr;
            this->_count = ptr._count;
            (*this->_count)++;
            return *this;
        }
    
        //重载operator*
        T& operator*()
        {
            if (this->_ptr)
            {
                return *(this->_ptr);
            }
        }
    
        //重载operator->
        T* operator->()
        {
            if (this->_ptr)
            {
                return this->_ptr;
            }
        }
    
        //析构函数
        ~shared_ptr()
        {
            (*this->_count)--;
            if (*this->_count == 0)
            {
                delete this->_ptr;
                delete this->_count;
            }
        }
    
        //引用计数
        int use_count()
        {
            return *this->_count;
        }
    };
    

    3、弱引用指针std::weak_ptr<T>

    共享资源的观察者,需要和 std::shared_ptr 一起使用,不影响资源的生命周期。
    注意事项:
    (1)弱引用指针,不会累计引用计数
    (2)weak_ptr只能通过shared_ptr或者weak_ptr来构造
    (3)主要应用场景:为了解决shared_ptr循环引用,导致内存无法释放问题
    (4)通过成员函数lock获取shared_ptr对象,然后再访问数据
    shared_ptr循环引用:

    class A
    {
    public:
        A() {};
        ~A() {};
        std::shared_ptr<B> b;
    private:
    
    };
    
    class B
    {
    public:
        B() {};
        ~B() {};
        std::shared_ptr<A> a;
    private:
    
    };
    
    int main()
    {
        //循环引用,无法析构
        std::shared_ptr<A> ptr_a = std::make_shared<A>();
        std::shared_ptr<B> ptr_b = std::make_shared<B>();
        ptr_a->b = ptr_b;
        ptr_b->a = ptr_a;
        return 1;
    }
    

    相关文章

      网友评论

          本文标题:C++智能指针

          本文链接:https://www.haomeiwen.com/subject/twuakrtx.html