shared_ptr与scoped_ptr都包装在堆上分配的动态对象,都重载了*和->操作符以模仿原始指针行为,但shared_ptr实现的是引用计数型的智能指针,当没有代码使用时计数为0,此时释放被包装的动态分配的内存。 shared_ptr可以被自由地拷贝和赋值。shared_ptr可以安全地放到标准容器中。 引用《boost程序库完全开发指南》中的话:“shared_ptr非常有价值、非常重要、非常有用。” shared_ptr有多种形式的构造函数,应用于各种可能的情形: 1.无参的shared_ptr()创建一个持有空指针的shared_ptr 2.shared_ptr(Y *p)获得指向类型T的指针p的管理权,同时引用计数置为1. 3.shared_ptr(shared_ptr const &r)从另一个shared_ptr获得指针的管理权, 引用计数加1 4.shared_ptr(std::auto_ptr<Y> &r)从一个auto_ptr获得指针的管理权,引用计数置为1 5.重载了=操作符,可以从另一个shared_ptr或auto_ptr获得指针的管理权。行为同构造函数。 6.shared_ptr(Y *p, D d)行为类似shared_ptr(Y *p),参数d指定了析构时的定制删除器。 reset()函数与scoped_ptr的reset()函数不同,它将引用计数减1 unique()在shared_ptr指针唯一所有者时返回true use_count()返回当前指针的引用计数。多应用于测试或调试,不提供高效率的操作,unique()速度更快。 支持比较,可以测试两个shared_ptr的相等或不等。if (a.get() == b.get()) { } shared_ptr<int> p(new int(1)); //引用计数置为1 shared_ptr<int> p2(p); //引用计数+1, 为2 cout << p.use_count() << endl;shared_ptr很好的消除了显式的delete调用,但构造还需要new.为了消除不对称性,也可以调用头文件<boost/make_shared.hpp>中的make_shared<T>()函数来消除new.
make_shared() 函数最多接受10个参数,然后传递给shared_ptr所包裹指针的类型的构造函数。
应用于标准容器
有两种方式可以将shared_ptr应用于标准容器,
1.将容器作为shared_ptr管理的对象,如shared_ptr<list<T>>,用法与普通shared_ptr没有区别
2.另一种用法是将shared_ptr作为容器的元素。如list<shared_ptr<T>>.因为shared_ptr支持拷贝语义和比较操作,符合标准容器对元素的需求。标准容器不能容纳auto_ptr和scoped_ptr.
定制删除器
shared_ptr有一种shared_ptr(Y *p, D d)形式的构造函数,第一个参数是要被管理的指针,第二个参数d可以是函数对象,也可以是函数指针。告诉shared_ptr在析构时不使用delete来操作指针,而是调用d(p).
即把delete(p)换成d(p),d(p)不能抛出异常。
get_deleter(shared_ptr<T>const& p)函数可以返回删除器的指针
例如
shared_ptr<FILE> fp(fopen("a.txt", "r"), fclose);
当离开作用域时,shared_ptr自动调用fclose关闭文件
shared_ptr高级用法
void*指针可以指向任意类型,shared_ptr<void>就是一个泛型指针容器,可以管理任意类型的指针。但同时也丧失了原来的类型信息,
在使用时可以用static_pointer_cast<T>转型为原来的指针。
基于shared_ptr<void>和删除器,shared_ptr<void>可以实现退出作用域时调用任意函数的效果。
如
{ shared_ptr<void> p((void*)0, func); }退出作用域时调用函数func()
shared_array
shared_array用于管理动态数组,接口与功能几乎与shared_ptr相同。
主要区别:
管理的指针p必须是new[]的结果而不是new表达式的结果
没有*, ->操作符重载,因为持有的不是一个普通指针
重载了[],可以像普通数组一样用下标访问元素
{ int *array = new int[100]; shared_ptr<int> sa(array); shared_ptr<int> sa2 = sa; //共享数组,引用计数增加 sa[0] = 0; //重载了[] }
boost库学习之 shared_ptr
时间: 2024-12-17 06:55:31
boost库学习之 shared_ptr的相关文章
c++ boost库学习三:实用工具
noncopyable 大家都知道定义一个空类的时候,它实际包含了构造函数,拷贝构造函数,赋值操作符和析构函数等. 这样就很容易产生一个问题,就是当用户调用A a(“^_^") 或者A c="^_^" 时会发生一些意想不到的行为,所以很多时候我们需要禁用这样的用法. 一种方法就是把拷贝构造函数和赋值操作符显式的定义为private,但是这样需要很多代码. 于是boost库为大家提供了一个简单的方法:只需要将类继承于noncopyable就可以了. #include "
c++ boost库学习一:时间和日期
timer类 #include <boost\timer.hpp> #include "iostream" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { boost::timer t; cout<<"max time span: "<<t.elapsed_max()/3600<<"h"<<endl; //596.5
boost库学习之regex
一.背景 项目中许多地方需要对字符串进行匹配,比如根据指定的过滤字符串来过滤文件名.刚开始是排斥使用boost库的,第一,我不熟悉boost库:第二,如果引入第三方库,就会增加库的依赖,这样的后果是,要么打包程序时,打包动态库,要么直接使用静态库编译,会使增大程序的大小. 刚开始是尝试自己写模糊匹配算法,很简单,就只支持_和%,这两个通配符,然后发现Linux下有一个fnmatch的函数,就是进行模糊匹配的,它支持shell通配符. 但是到最后发现,当需要区别很相似的字符串时,模糊匹配就不行了,
Boost库学习之旅入门篇
学习及使用Boost库已经有一段时间了,Boost为我的日常开发中带来了极大的方便,也使得我越来越依赖于boost库了.但boost功能太多,每次使用还是得翻看以前的 资料,所以为了以后可以更方便的使用,在此对常用的功能作一个总结,也希望以此与大家共勉. boost库下载,Svn地址: http://svn.boost.org/svn/boost/trunk 编译源码 编译boost库自带脚本解释工具: 使用vs自带命令行工具Visual Studio 命令提示(2010),运行bat脚本boo
boost库学习之开篇
本系列文章使用boost_1.58.0版本. 一.欢迎使用boost C++库 boost致力于提供一个免费的.便携的源代码级的库. 我们重视那些与C++标准一起工作良好的库.boost库将要成为一个应用广泛的库,成为应用程序可以依赖的平台.boost证书估计商业和非商业机构使用它. 我们的目标是建立已存在的练习而且提供对于库具体实现的引用以至于boost库适合于最后的标准.十个boost库已经包含在C++标准委员会的TR1而且将要被包含在即将到来的C++标准版本中.更多的boost库将目标放在
boost库学习之 scoped_ptr scoped_array
boost.smart_ptr库提供了六种智能指针:scoped_ptr.scoped_array.shared_ptr.shared_array.week_ptr和intrusive_ptr. 说到智能指针,我们会想到c++98标准中的自动指针auto_ptr. auto_ptr获取指针所有权后,离开作用域时自动释放该指针指向的堆内存.也可以转移指针的所有权. auto_ptr<A> ap_a1(new A); auto_ptr<A> ap_a2(ap_a1); //发生所有权转
boost库学习之 date_time库
date_time库是一个全面灵活的日期时间库,提供时间相关的各种所需功能,也是一个比较复杂的库.它支持从1400-01-01到9999-12-31之间的日期计算.使用时包含#include <boost/date_time/gregorian/gregorian.hpp>头文件, 引用boost::gregorian;命名空间. 日期 date是date_time库中的核心类.以天为单位表示时间点. date d1; //无效日期 date d2(2015, 1, 4); date d
boost库学习之 pool库
简单来说内存池预先分配了一块大的内存空间,然后在其中使用某种算法高效快速的自定制内存分配. pool库包含四个组成部分,最简单的pool,分配类实例的object pool,单件内存池singleton_tool和用于标准库的pool_alloc. 为了使用pool组件,需要包含<boost/pool/pool.hpp>头文件. 操作函数: pool的构造函数接受一个size_type类型的整数request_size,指示每次pool分配内存块的大小 成员函数get_request_size
boost库学习之 timer库
timer是一个很小的库,提供简易的时间度量和进度显示,包括timer.progress_timer.progress_display三个类.不适合高精度的时间测量任务,精度依赖于操作系统或编译器,可提供的最大时间跨度只有几百个小时,不适合大跨度的时间段测量. timer类 先来看一下标准库如何计时: #include <iostream> #include <ctime> using namespace std; int main() { clock_t begin, end;