智能指针:关于enable_shared_from_this的使用

文章讨论了在C++中使用智能指针shared_ptr时可能出现的问题,特别是关于引用计数和内存释放的细节。通过示例代码展示了如何正确初始化和管理共享资源,强调了使用拷贝构造函数确保引用计数一致的重要性。同时,解释了enable_shared_from_this模板类的作用,它允许对象在内部生成指向自身的shared_ptr,防止因不正确使用导致的对象重复析构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 带引用计数的智能指针shared_ptr的一个常见问题

    #include<iostream>
    #include<memory>
    using namespace std;
    
    int main()
    {
        int* p = new int();
        auto ptr_1 = shared_ptr<int>(p);
        auto ptr_2 = shared_ptr<int>(p);
        cout << ptr_1.use_count() << " " //1
            << ptr_2.use_count() << endl; //1
        system("pause");
        return 0;
    }
    

    上面通过普通指针p来初始化两个shared_ptr指针,会导致p指向的堆内存重复释放,因为这个两个shared_ptr对p指向的内存的引用计数都是1

  • 正确做法:

    #include<iostream>
    #include<memory>
    using namespace std;
    
    int main()
    {
        int* p = new int();
        auto ptr_1 = shared_ptr<int>(p);
        auto ptr_2 = ptr_1 ;
        cout << ptr_1.use_count() << " " //2
            << ptr_2.use_count() << endl; //2
        system("pause");
        return 0;
    }
    

    应该通过拷贝构造,来保证不同的shared_ptr对相同的堆内存引用计数保持一致,当每个share_ptr释放的时候引用计数-1,引用计数到0的时候释放堆内存。

  • enable_shared_from_this

    • 是个可以被继承的模板类,里面有个shared_from_this()的成员函数,可以返回指向当前对象的智能指针shared_ptr,并保持对当前对象引用计数的一致性;

    • 先看下面一段存在问题代码:

      #include<iostream>
      #include<memory>
      using namespace std;
      
      class A :public enable_shared_from_this<A>
      {
      public:
          shared_ptr<A> get()
          {
              return shared_ptr<A>(this); 
              如果通过this指针传递当前指向当前对象的智能指针会导致引用计数一致
          }
      };
      int main()
      {
          A* p = new A();
          auto ptr_1 = shared_ptr<A>(p);
          auto ptr_2(ptr_1->get());
          cout << ptr_1.use_count() << " " //1
              << ptr_2.use_count() << endl; //1
          system("pause");
          return 0;
      }
      

      如果当前实例对象被智能指针管理, 想通过实例对象的成员函数传递指向当前对象的shared_ptr,直接通过this指针构建一个shared_ptr是不安全的,会导致当前对象被重复析构。

    • 如果当前对象被shared_ptr管理,且需要在当前对象内部的成员函数中返回当前指向当前对象shared_ptr,并保持引用计数一致,就可以使用enable_shared_from_this

      #include<iostream>
      #include<memory>
      using namespace std;
      class A :public enable_shared_from_this<A>
      {
      public:
          shared_ptr<A> get()
          {
              return shared_from_this();
          }
      };
      int main()
      {
          A* p = new A();
          auto ptr_1 = shared_ptr<A>(p);
          auto ptr_2(ptr_1->get());
          cout << ptr_1.use_count() << " " //2
              << ptr_2.use_count() << endl; //2
          system("pause");
          return 0;
      }
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值