19、C++11 shared_ptr智能指针

  • C++98/03 标准中,支持使用 auto_ptr 智能指针来实现堆内存的自动回收;
  • C++11 新标准在废弃 auto_ptr 的同时,增添了 unique_ptr、shared_ptr 以及 weak_ptr 这 3 个智能指针来实现堆内存的自动回收。
shared_ptr智能指针

每种智能指针都以类模板的方式实现。shared_ptr<T>的定义位于<memory>头文件,并位于std命名空间中。

// 每次使用加这两行代码
#include<memory>
using namespace std;

shared_ptrunique_ptr、weak_ptr 不同之处:

  • 多个shared_ptr智能指针可以共同使用一块内存。
    • 因为shared_ptr在实现上采用的是引用计数机制;
    • shared_ptr放弃堆内存的使用,该堆内存引用计数减1,不会影响其他的shared_ptr智能指针。
    • 只有当堆内存引用计数为0时,该堆内存才会自动释放。
1、share_ptr智能指针的创建

shared_ptr<T>类模板中,提供了多种实用的构造函数。

a) shared_ptr<T>类型的空智能指针构造:

std::shared_ptr<int> p1;    //不传入任何实参
std::shared_ptr<int> p2(nullptr); //传入空指针 nullptr
  • shared_ptr指针,其初始引用计数为0,而不是1

b) 明确指向

shared_ptr<int> p3(new int(10));   //指向一块存有 10 这个 int 类型数据的堆内存空间
// C++11提供 make_shared<T> 模板函数用于初始化 shared_ptr
shared_ptr<int> p3 = make_shared<int>(10);  //与上相同

c) 拷贝构造函数和移动构造函数

//调用拷贝构造函数
shared_ptr<int> p4(p3) ;    // 或者shared_ptr<int> p4 = p3;
//调用移动构造函数
shared_ptr<int> p5(move(p4));  //或者 shared_ptr<int> p5 = move(p4);
  • 用 p3 来初始化 p4,由于 p3 是左值,因此会调用拷贝构造函数
    • 如果P3为空智能指针,则P4也为空智能指针,其引用计数初始值为0
    • 如果P3不为空,指向堆内存,则P4和P3指向同一块堆内存,同时该堆空间的引用计数会加1。
  • 对于 std::move(p4) 来说,该函数会强制将 p4 转换成对应的右值,因此初始化 p5 调用的是移动构造函数
    • 用 std::move(p4) 初始化 p5:p5拥有p4的堆内存,p4变成了空智能指针。

注意:同一普通指针不能同时为多个 shared_ptr 对象赋值,否则会导致程序发生异常。例如:

int *ptr = new int;
shared_ptr<int> p1(ptr);
std::shared_ptr<int> p2(ptr);//错误

d) 在初始化 shared_ptr 智能指针时,还可以自定义所指堆内存的释放规则,这样当堆内存的引用计数为 0 时,会优先调用我们自定义的释放规则。

  • 在某些场景中,自定义释放规则是很有必要的:

    • 例如shared_ptr指针默认的释放规则是不支持 动态数组的释放 ,只能自定义对应的释放规则,才能正确地释放申请的堆内存。

    • 动态数组的释放也可以使用C++11提供的default_delete<T>模板类:

      // 释放动态数组:指定 default_delete 作为释放规则
      shared_ptr<int> p6(new int[10], default_delete<int[]> );
      
      // 释放动态数组:自定义释放规则
      void deleteInt(int *p)
      {
          delete []p;
      }
      shared_ptr<int> p7(new int[10],deleteInt);
      
      // 使用lambda表达式
      shared_ptr<int> p7(new int[10], [](int *p){ delete []p; });
      
2、shared_ptr<T>模板类提供的成员方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K4viogUl-1630380336889)(H:\Xmind共享\C++\面试准备\C++\C++11博客.assets\image-20210608092734617.png)]

除此之外,C++11 标准还支持同一类型的 shared_ptr 对象,或者 shared_ptr 和 nullptr 之间,进行 ==,!=,<,<=,>,>= 运算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值