原标题:全面分析 C++ Boost 智能指针! | CSDN 博文精选
作者 | .NY&XX
责编 | 屠敏
出品 | CSDN 博客
为什么要运用智能指针
C++没有供给相似JAVA的废物收回机制,因而Boost能够经过智能指针来办理内存防止一些问题。C++承继C高效灵敏地指针,可是相同带了了许多问题:
- 内存走漏
- 野指针
- 越界拜访
什么是智能指针
智能指针是一种像指针的C++目标,但它能够在目标不运用的时分自己毁掉掉。尽管STL供给了auto_ptr,可是因为不能同容器一同运用(不支撑复制和赋值操作),因而很少有人运用。它是Boost各组件中,运用最为广泛的一个。运用智能指针需包括以下头文件,假如只运用智能指针 shared_ptr 能够只包括同名头文件。
#include<boost/smart_ptr.hpp>
usingnamespaceboost;
Boost首要包括以下几种智能指针:
boost::scope_ptr
首要特点
- scoped_ptr 是Boost 供给的一个简略的智能指针只限于效果域内运用
- 指针办理权不行搬运,不支撑复制结构函数与赋值操作。
这种智能指针只限于效果域内运用,无法搬运内置指针的办理权(不支撑复制、=赋值等) 可是效果也很显然。例如:
假定界说到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 [],多了下标拜访操作,其他相似。
- 结构函数指针有必要是 new[] 的成果,而不能是 new 表达式的成果
- 没有 *, -> 操作符重载,因为 scoped_array 持有的不是一个一般指针
- 析构函数运用 delete[] 开释资源,而不是 delete
- 供给 operator[] 操作符重载,能够像一般数组相同用下标拜访
- 没有 begin, end 等相似容器迭代器操作函数
详细用法
scoped_array 轻巧方便,没有给程序添加额外负担,可是 scoped_array 功用有限,不能动态添加,也没有迭代器支撑,不能调配 STL 算法,仅有一个朴实的“裸”数组接口。在需求动态数组的情况下咱们应该运用 std::vector 。例如:
boost::shared_ptr
首要特点
boost.smart_ptr 库中最有价值百科,最重要的组成部分。支撑复制结构函数、支撑赋值操作。重载了*和->操作符用来仿照原始指针的行为。现在已成为tr1规范的一部分,开展自原始的auto_ptr,内置引证计数。引证指针计数器记载有多少个引证指针指向同一个目标,假如最终一个引证指针被毁掉的时分,那么就毁掉目标自身。
- 支撑复制结构函数,赋值操作。
- 重载 * 和 -> 操作符仿照原始指针。
- 内置引证计数。
可是,运用的时分需求留意以下几点:
- 同scope_ptr相同,制止get得到指针地址后,履行delete。
- 制止循环引证,不然会出内存走漏。
- 不能作为函数的暂时参数。
- shared_ptr是线程安全的。
- 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
热 文 推 荐
责任编辑: