• C++之weak_ptr与shared_ptr智能指针实例(一百九十五)


    简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

    优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀

    人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

    更多原创,欢迎关注:Android系统攻城狮

    欢迎关注Android系统攻城狮

    1.前言

    本篇目的:C++之weak_ptr与shared_ptr强弱智能指针用法

    在C++中,weak_ptr和shared_ptr是智能指针的两种类型,用于解决资源管理和避免内存泄漏的问题。

    1. shared_ptr(共享指针):

      • shared_ptr允许多个智能指针共享同一个对象的所有权。
      • 每个shared_ptr都维护一个引用计数,它记录有多少个shared_ptr指向同一对象。
      • 只有当引用计数变为0时,shared_ptr才会自动析构并释放资源。
      • 可以通过std::make_shared或std::shared_ptr构造函数来创建shared_ptr对象。
    2. weak_ptr(弱指针):

      • weak_ptr是一种不控制对象生命周期的智能指针,它指向一个由shared_ptr管理的对象。
      • weak_ptr可以观测shared_ptr的生命周期,但不会增加引用计数。
      • 使用lock()函数可以获取一个有效的shared_ptr对象来访问观测的资源。
      • 如果shared_ptr已经释放了资源,则lock()函数会返回一个空的shared_ptr。

    使用shared_ptr的好处:

    • 避免内存泄漏:通过引用计数,当没有shared_ptr指向对象时,会自动进行资源释放。
    • 安全共享对象:多个shared_ptr可以共享访问同一个对象,不会出现多次释放同一资源的问题。

    使用weak_ptr的好处:

    • 避免循环引用:当对象之间存在互相引用而没有外部引用时,使用weak_ptr作为其中一个引用可以打破循环引用,避免内存泄漏。
    • 安全观测资源:通过lock()函数,可以安全地观测shared_ptr所管理的对象,避免悬空指针的问题。

    需要注意的是,当使用weak_ptr时,需要注意判断返回的shared_ptr是否为空,以处理shared_ptr已释放资源的情况。另外,weak_ptr并不拥有指向的资源,因此不能直接通过weak_ptr访问资源的成员函数或成员变量,需要使用lock()函数获取shared_ptr对象后才能进行访问。

    在C++中,std::weak_ptr类提供了一个成员函数lock(),用于获取与其关联的std::shared_ptr对象。

    lock()函数的实现如下:

    template<class T>
    std::shared_ptr<T> std::weak_ptr<T>::lock() const noexcept;
    
    • 1
    • 2

    lock()函数的作用是尝试获取与std::weak_ptr对象关联的std::shared_ptr对象。如果关联的std::shared_ptr对象仍然存在,lock()函数会返回一个有效的、指向相同目标的std::shared_ptr对象。如果关联的std::shared_ptr已被销毁,lock()函数将返回一个空指针(nullptr)。

    lock()函数是线程安全的,并且在多线程环境中可以正确地处理std::shared_ptr的引用计数和资源管理。

    使用lock()函数可以安全地访问由std::weak_ptr进行观测的对象,避免了悬空指针的风险,同时也不会增加引用计数。

    2.应用实例

    #include 
    #include 
    #include 
    
    using namespace std;
    
    class C2ComponentStore {
    public:
      C2ComponentStore() {}
      ~C2ComponentStore() {}
    
      string name = "123456789";
    };
    
    int main() {
      //1.创建一个weak_ptr对象platformStore,初始为空
      std::weak_ptr<C2ComponentStore> platformStore;
      //2.通过lock()函数获取platformStore的shared_ptr对象
      std::shared_ptr<C2ComponentStore> store = platformStore.lock();
    
    
      //3.如果获取的shared_ptr对象为空
      if(store == nullptr) {
        //4.创建一个新的shared_ptr对象store,并使用make_shared初始化
        store = std::make_shared<C2ComponentStore>();
    
        //5.将store赋值给platformStore
        platformStore = store;
      }
    
      printf("store.name = %s\n",store->name.c_str());
      printf("platformStore.name = %s\n",platformStore.lock()->name.c_str());
    
      return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    以上代码中,platformStore.lock()的调用将尝试获取与platformStore关联的std::shared_ptr对象。如果对象仍然有效,那么返回的std::shared_ptr对象是有效的,可以使用它来访问对象的成员变量和方法。如果对象已被销毁,那么返回的std::shared_ptr对象将是一个空指针。

  • 相关阅读:
    spring boot项目未将resource目录标志为资源目录导致配置文件无效因而运行报错问题
    字符串压缩(一)之ZSTD
    【写作神器】Markdown编辑器实用语法
    Qt(day4)
    2023国赛B题:多波束测线问题 评阅要点完整分析
    关于 vim - YouCompleteMe 的安装
    DNS解析
    大集合里查询数据-布隆过滤器
    uniapp瀑布流布局写法
    css实现流星划过动画
  • 原文地址:https://blog.csdn.net/u010164190/article/details/132829462