• C++智能指针



    一、智能指针的目的和基本原理

    一般new出来的对象会用普通指针引用,此时申请的堆上的资源需要我们手动使用delete进行资源释放。如果忘记delete或者delete之前程序出现未可预知的意外,之前申请的资源就不能正常释放,造成内存泄露;
     
    智能指针是对裸指针(普通指针)的封装,智能指针利用了栈上对象在跳出作用域会自动析构的原理,让智能指针去管理资源。所以智能指针对象一般不能new。
     

    二、不带引用计数的智能指针

    2.1 auto_ptr

    auto_ptr只能管理一个对象,如果使用拷贝构造函数进行auto_ptr初始化,

    #include "iostream"
    #include "string"
    
    using namespace std;
    
    int main() {
        auto_ptr<int> p1(new int(10));
        auto_ptr<int> p2(p1); 
        *p1 = 20; //此处会出现问题,因为把对象的控制权转让给了p2,之前的p1底层会自动指向nullptr
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    auto_ptr已经过期,如上的这种问题导致C++并不建议使用auto_ptr。
     

    2.2 scoped_ptr

    基于以上auto_ptr的问题,scoped_ptr直接禁止使用拷贝构造函数和赋值重载运算符函数。scoped_ptr部分源码如下所示:

    template<class T> class scoped_ptr // noncopyable
    {
    private:
        T * px;
    	
        scoped_ptr(scoped_ptr const &);
        scoped_ptr & operator=(scoped_ptr const &);
     
        typedef scoped_ptr<T> this_type;
    		
    	//以下两个函数直接被删除,禁止使用
        void operator==( scoped_ptr const& ) const;
        void operator!=( scoped_ptr const& ) const;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

     

    2.3 unique_ptr

    从名字就可以看出来unique_ptr只能管理一个资源。
    而且unique_ptr也删除了拷贝构造函数和赋值运算符重载函数。
    但是unique_ptr提供了一个带右值引用的拷贝构造函数和赋值运算符重载函数,使用方法如下所示:

    // 示例1
    unique_ptr<int> ptr(new int);
    //如下相当于把对象的控制权从ptr转给了ptr2
    unique_ptr<int> ptr2 = std::move(ptr); // 使用了右值引用的拷贝构造
    ptr2 = std::move(ptr); // 使用了右值引用的operator=赋值重载函数
    
    • 1
    • 2
    • 3
    • 4
    • 5

     

    三、带引用计数的智能指针

     

    3.1 shared_ptr

    如名字所示,多个智能指针对象指向同一个内存资源,智能指针对象里维护了一个引用计数器对象,表示当前指针指向的对象被多少个智能指针引用。当引用计数减到0的时候才真正的进行对象的析构。
    shared_ptr维护的计数器对象是在new在堆上的,
    shared_ptr又叫做强智能指针。
     

    3.2 weak_ptr

    在这里插入图片描述
    如上的情况叫做交叉引用,A对象和B对象的引用计数都是2,如果使用shared_ptr,如果ptrA或者ptrB不再引用对象,对象本应该被释放,但是实际上引用计数不为0,对象不能被释放,这种情况就要使用weak_ptr。
     
    弱智能指针weak_ptr区别于shared_ptr之处在于:

    1、weak_ptr不会改变资源的引用计数,只是一个观察者的角色,通过观察shared_ptr来判定资源是否存在
    2、weak_ptr持有的引用计数,不是资源的引用计数,而是同一个资源的观察者的计数
    3、weak_ptr没有提供常用的指针操作,无法直接访问资源,需要先通过lock方法提升为shared_ptr强智能指针,才能访问资源。
     
    从shared_ptr和weak_ptr之间的区别可以看出,在对象内部引用其他对象的时候使用weak_ptr,外部的时候使用shared_ptr。

  • 相关阅读:
    漏洞赏金猎人开源工具集合,自动辅助渗透测试工具
    特征工程学习笔记
    知识产权的国际保护
    Coredump-Z: map 释放后再使用的问题;多线程
    服务器应用程序不可用的原因是什么引起的
    程序分享--排序算法--计数排序
    商品管理系统数据库设计--SQL Server
    iperf安装与使用
    微信小程序 - 方法
    椭圆加密C#实现
  • 原文地址:https://blog.csdn.net/weixin_39861267/article/details/127824068