您当前的位置:即刻健康网资讯正文

全面剖析C++Boost智能指针!CSDN博文精选

2019-08-21 12:20:09  阅读:5014 作者:CSDN 浏览次数:5014

原标题:全面分析 C++ Boost 智能指针! | CSDN 博文精选

作者 | .NY&XX

责编 | 屠敏

出品 | CSDN 博客

为什么要运用智能指针

C++没有供给相似JAVA的废物收回机制,因而Boost能够经过智能指针来办理内存防止一些问题。C++承继C高效灵敏地指针,可是相同带了了许多问题:

  1. 内存走漏
  2. 野指针
  3. 越界拜访

什么是智能指针

智能指针是一种像指针的C++目标,但它能够在目标不运用的时分自己毁掉掉。尽管STL供给了auto_ptr,可是因为不能同容器一同运用(不支撑复制和赋值操作),因而很少有人运用。它是Boost各组件中,运用最为广泛的一个。运用智能指针需包括以下头文件,假如只运用智能指针 shared_ptr 能够只包括同名头文件。

#include<boost/smart_ptr.hpp>

usingnamespaceboost;

Boost首要包括以下几种智能指针:

boost::scope_ptr

首要特点

  1. scoped_ptr 是Boost 供给的一个简略的智能指针只限于效果域内运用
  2. 指针办理权不行搬运,不支撑复制结构函数与赋值操作。

这种智能指针只限于效果域内运用,无法搬运内置指针的办理权(不支撑复制、=赋值等) 可是效果也很显然。例如:

假定界说到delete之中…发生了反常,那么ptr就无法被delete,造成了内存走漏。运用scoped_ptr就能够很好处理这个问题,只需求new的时分放到scoped_ptr之中就能够了。

详细用法

假定:

scoped_ptr ptr_t(newT); // 假定内置指针为p_t

则:

  • ptr_t->get,回来内部办理的指针,但制止在get出来的指针上履行delete。
  • ptr_t->xxx,等同于p_t->xxx ptr_t.reset,delete内部持有的p_t。
  • 假定T支撑直接赋值,*ptr_t = xxx。

再次着重,scoped_ptr不能做复制、赋值等搬运指针办理权限的作业。因而,class内置域为scoped_ptr是不允许的,除非class也制止复制、赋值。

boost::scope_array

首要特点

同 boost::scoped_ptr 根本相同,仅仅承受数组的new [],多了下标拜访操作,其他相似。

  1. 结构函数指针有必要是 new[] 的成果,而不能是 new 表达式的成果
  2. 没有 *, -> 操作符重载,因为 scoped_array 持有的不是一个一般指针
  3. 析构函数运用 delete[] 开释资源,而不是 delete
  4. 供给 operator[] 操作符重载,能够像一般数组相同用下标拜访
  5. 没有 begin, end 等相似容器迭代器操作函数

详细用法

scoped_array 轻巧方便,没有给程序添加额外负担,可是 scoped_array 功用有限,不能动态添加,也没有迭代器支撑,不能调配 STL 算法,仅有一个朴实的“裸”数组接口。在需求动态数组的情况下咱们应该运用 std::vector 。例如:

boost::shared_ptr

首要特点

boost.smart_ptr 库中最有价值百科,最重要的组成部分。支撑复制结构函数、支撑赋值操作。重载了*和->操作符用来仿照原始指针的行为。现在已成为tr1规范的一部分,开展自原始的auto_ptr,内置引证计数。引证指针计数器记载有多少个引证指针指向同一个目标,假如最终一个引证指针被毁掉的时分,那么就毁掉目标自身。

  1. 支撑复制结构函数,赋值操作。
  2. 重载 * 和 -> 操作符仿照原始指针。
  3. 内置引证计数。

可是,运用的时分需求留意以下几点:

  1. 同scope_ptr相同,制止get得到指针地址后,履行delete。
  2. 制止循环引证,不然会出内存走漏。
  3. 不能作为函数的暂时参数。
  4. shared_ptr是线程安全的。
  5. shared_ptr支撑强制类型转化,假如界说了一个U能够强制转化到T(因为T是U的基类),那么shared_ptr也能够强制转化到shared_ptr。

详细用法

详细运用比如如下:

当遇到深复制问题时,假如成员变量是shared_ptr类型能够考虑不必自己编写复制和赋值结构函数。例如:

实践上,智能指针赋值复制的一起,引证计数也加1了。在默许析构函数也是如此,析构函数履行之后,会调用类A的析构函数,查看引证计数都为0后,会delete掉这个int。然后完美的完结了无内存走漏的、无内存犯错的、多个实例之间的指针变量同享。

boost::weak_ptr

首要特点

weak_ptr 被规划为与 shared_ptr 一起作业,能够从一个 shared_ptr 或许另一个 weak_ptr 目标结构,取得资源的观测权。可是 weak_ptr 没有同享资源,它的结构不会引起指针引证计数的添加,一起,在析构的时分也不回引起引证计数的削减。

详细用法

shared_ptr有个丧命缺点,循环引证不能够主动收回。看如下的比如:

运转成果:

因为A和B彼此引证,它们的计数永久都为2,所以这样运用shared_ptr必然会导致内存走漏。为了处理这个问题,能够选用boost::weak_ptr来间隔穿插引证中的回路;boost::weak_ptr有必要从一个boost::share_ptr或另一个boost::weak_ptr转化而来,这也阐明,进行该目标的内存办理的是那个强引证的boost::share_ptr。boost::weak_ptr仅仅供给了对办理目标的一个拜访手法。弱引证不更改引证计数,相似一般指针,只要把循环引证的一方运用弱引证,即可免除循环引证。例如:

运转成果:

shared_ptr 同 weak_ptr的比较:

intrusive_ptr

首要特点

尽管boost::shared_ptr 比一般指针供给了更完善的功用。有一个小小的价值,那就是一个同享指针比一般指针占用更多的空间,每一个目标都有一个同享指针,这个指针有引证计数器以便于开释。boost::intrusive_ptr是一种“侵入式”的引证计数指针,是boost::shared_ptr的刺进式版别。实践并不供给引证计数功用,而是要求被存储的目标自己完结引证计数功用。能够运用于以下两种景象:

  • 对内存占用要求十分严厉,智能指针巨细有必要与裸指针相同;
  • 现存代码现已有了引证计数机制办理的目标。而又没有时刻去保护它(或许现已不能获取这些代码了)。

intrusive_ptr与运用shared_ptr比较,有两个首要的不同之处。第一个是你需求供给引证计数的机制。第二个是把this当成智能指针是合法的。

详细用法

  • 要运用 boost::intrusive_ptr, 要包括 “boost/intrusive_ptr.hpp” 并界说两个一般函数 intrusive_ptr_add_ref 和 intrusive_ptr_release. 它们都要承受一个参数。
  • 一般最好泛化这两个函数,简略地调用被办理类型的成员函数去完结作业。

咱们来看一个比如,RefCount供给了计数器功用:

在主函数中测验一下:

运转成果:

声明:本文为CSDN博主「.NY&XX」的原创文章,版权归作者一切,如需转载请联络作者。

原文:https://blog.csdn.net/songguangfan/article/details/96361648

热 文 推 荐

责任编辑:

“如果发现本网站发布的资讯影响到您的版权,可以联系本站!同时欢迎来本站投稿!

相关文章
国内首个健康主题综合型电商节 天猫国际持续引领第四餐前沿
暂别南昌,相约天津!为智慧校园体育场景持续助力,沃莱科技第81届中国教育装备展圆满收官!
强迫未婚女性弃婴英国威尔士地方政府将道歉