加入收藏 | 设为首页 | 会员中心 | 我要投稿 大连站长网 (https://www.0411zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

C++11 shared_ptr智能指针 超级具体

发布时间:2022-07-14 01:28:27 所属栏目:语言 来源:互联网
导读:在实际的 C++ 开发中,我们经常会遇到诸如程序运行中突然崩溃、程序运行所用内存越来越多最终不得不重启等问题,这些问题往往都是内存资源管理不当造成的。比如: 有些内存资源已经被释放,但指向它的指针并没有改变指向(成为了野指针),并且后续还在使
  在实际的 C++ 开发中,我们经常会遇到诸如程序运行中突然崩溃、程序运行所用内存越来越多最终不得不重启等问题,这些问题往往都是内存资源管理不当造成的。比如:
  有些内存资源已经被释放,但指向它的指针并没有改变指向(成为了野指针),并且后续还在使用;
  有些内存资源已经被释放,后期又试图再释放一次(重复释放同一块内存会导致程序运行崩溃);
  没有及时释放不再使用的内存资源,造成内存泄漏,程序占用的内存资源越来越多。
 
  所谓智能指针,可以从字面上理解为“智能”的指针。具体来讲,智能指针和普通指针的用法是相似的,不同之处在于,智能指针可以在适当时机自动释放分配的内存。也就是说,使用智能指针可以很好地避免“忘记释放内存而导致内存泄漏”问题出现。由此可见,C++ 也逐渐开始支持垃圾回收机制了,尽管目前支持程度还有限。
  C++ 智能指针底层是采用引用计数的方式实现的。简单的理解,智能指针在申请堆内存空间的同时,会为其配备一个整形值(初始值为 1),每当有新对象使用此堆内存时,该整形值 +1;反之,每当使用此堆内存的对象被释放时,该整形值减 1。当堆空间对应的整形值为 0 时,即表明不再有对象使用它,该堆空间就会被释放掉。
 
  接下来,我们将分别对 shared_ptr、unique_ptr 以及 weak_ptr 这 3 个智能指针的特性和用法做详细的讲解,本节先介绍 shared_ptr 智能指针。
  C++11 shared_ptr智能指针
  实际上,每种智能指针都是以类模板的方式实现的,shared_ptr 也不例外。shared_ptr<T>(其中 T 表示指针指向的具体数据类型)的定义位于<memory>头文件,并位于 std 命名空间中,因此在使用该类型指针时,程序中应包含如下 2 行代码:
  #include <memory>
  using namespace std;
  注意,第 2 行代码并不是必须的,也可以不添加,则后续在使用 shared_ptr 智能指针时,就需要明确指明std::。
 
  值得一提的是,和 unique_ptr、weak_ptr 不同之处在于,多个 shared_ptr 智能指针可以共同使用同一块堆内存。并且,由于该类型智能指针在实现上采用的是引用计数机制,即便有一个 shared_ptr 指针放弃了堆内存的“使用权”(引用计数减 1),也不会影响其他指向同一堆内存的 shared_ptr 指针(只有引用计数为 0 时,堆内存才会被自动释放)。
  1、shared_ptr智能指针的创建
  shared_ptr<T> 类模板中,提供了多种实用的构造函数,这里给读者列举了几个常用的构造函数(以构建指向 int 类型数据的智能指针为例)。
 
  1)  通过如下 2 种方式,可以构造出 shared_ptr<T> 类型的空智能指针:
  std::shared_ptr<int> p1;             //不传入任何实参
  std::shared_ptr<int> p2(nullptr);    //传入空指针 nullptr
  注意,空的 shared_ptr 指针,其初始引用计数为 0,而不是 1。
 
  2) 在构建 shared_ptr 智能指针,也可以明确其指向。例如:
  std::shared_ptr<int> p3(new int(10));
  由此,我们就成功构建了一个 shared_ptr 智能指针,其指向一块存有 10 这个 int 类型数据的堆内存空间。
 
  同时,C++11 标准中还提供了 std::make_shared<T> 模板函数,其可以用于初始化 shared_ptr 智能指针,例如:
  std::shared_ptr<int> p3 = std::make_shared<int>(10);
  以上 2 种方式创建的 p3 是完全相同。
 
  2、shared_ptr<T>模板类提供的成员方法
  为了方便用户使用 shared_ptr 智能指针,shared_ptr<T> 模板类还提供有一些实用的成员方法,它们各自的功能如表 1 所示。
 
  shared_ptr<T>模板类常用成员方法
  成员方法名 功 能
  operator=() 重载赋值号,使得同一类型的 shared_ptr 智能指针可以相互赋值。
  operator*() 重载 * 号,获取当前 shared_ptr 智能指针对象指向的数据。
  operator->() 重载 -> 号,当智能指针指向的数据类型为自定义的结构体时,通过 -> 运算符可以获取其内部的指定成员。
  swap() 交换 2 个相同类型 shared_ptr 智能指针的内容。
  reset() 当函数没有实参时,该函数会使当前 shared_ptr 所指堆内存的引用计数减 1,同时将当前对象重置为一个空指针;当为函数传递一个新申请的堆内存时,则调用该函数的 shared_ptr 对象会获得该存储空间的所有权,并且引用计数的初始值为 1。
  get() 获得 shared_ptr 对象内部包含的普通指针。
  use_count() 返回同当前 shared_ptr 对象(包括它)指向相同的所有 shared_ptr 对象的数量。
  unique() 判断当前 shared_ptr 对象指向的堆内存,是否不再有其它 shared_ptr 对象再指向它。
  operator bool() 判断当前 shared_ptr 对象是否为空智能指针,如果是空指针,返回 false;反之,返回 true。
   除此之外,C++11 标准还支持同一类型的 shared_ptr 对象,或者 shared_ptr 和 nullptr 之间,进行 ==,!=,<,<=,>,>= 运算。

(编辑:大连站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!