winston 发表于 2012-5-3 10:49:40

boost笔记:智能指针--概述

boost::scoped_ptr<T>http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/scoped_ptr.htm

scoped_ptr用于确保能够正确地删除动态分配(new)的对象。scoped_ptr永远不能被复制或被赋值!因此scoped_ptr拥有它所指向的资源的所有权,并永远不会放弃这个所有权。scoped_ptr构造时即拥有动态分配资源的所有权,直到使用reset()函数重新指定新的资源,或者超出作用域而释放所有权。
scoped_ptr的实现和std::auto_ptr非常类似,都是利用了一个栈上的对象去管理一个堆上的对象,从而使得堆上的对象随着栈上的对象销毁时自动删除。不同的是,scoped_ptr有着更严格的使用限制——不能拷贝。这就意味着:scoped_ptr指针是不能转换其所有权的。
boost::scoped_ptr的特点:

[*]不能转换所有权
scoped_ptr所管理的对象生命周期仅仅局限于一个区间(该指针所在的"{}"之间),无法传到区间之外,这就意味着scoped_ptr对象是不能作为函数的返回值的(std::auto_ptr可以)。
[*]不能共享所有权
这点和std::auto_ptr类似。这个特点一方面使得该指针简单易用。另一方面也造成了功能的薄弱——不能用于stl的容器中。
[*]不能用于管理数组对象
由于scoped_ptr是通过delete来删除所管理对象的,而数组对象必须通过delete []来删除,因此scoped_ptr是不能管理数组对象的,如果要管理数组对象需要使用boost::scoped_array类。
boost::scoped_ptr的使用场景:

[*]在可能有异常抛出的作用域里使用指针
[*]函数里有几条控制路径,指针在操作作用域后需要释放
[*]动态分配对象的生存期应被限制于特定的作用域内
[*]异常安全非常重要时(始终如此!)
boost::scoped_array<T>http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/scoped_array.htm

scoped_array用于确保能够正确地删除动态分配(new[])的数组对象。
scoped_array与scoped_ptr均不能共享所有权,不能转移所有权。不同的是scoped_array提供了operator[]来模仿一个裸数组。
scoped_array是比普通的动态分配数组更好用。它处理了动态分配数组的生存期管理问题,就如scoped_ptr管理对象指针的生存期一样。只有当你需要确保数组的大小是固定的时候,才使用boost::scoped_array来替代std::vector。
boost::shared_ptr<T>http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/shared_ptr.htm

boost::shared_ptr的管理机制其实并不复杂,就是对所管理的对象进行了引用计数,当新增一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数加一;减少一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数减一,如果该对象的引用计数为0的时候,说明没有任何指针对其管理,才调用delete释放其所占的内存。
boost::shared_ptr的特点:

[*]在内部维护一个引用计数器, 当有一个指针指向这块内存区域是引用计数+1, 反之-1, 如果没有任何指针指向这块区域,引用计数器为0,释放内存区域。
[*]可以共享和转移所有权。
[*]可以被标准库的容器所使用
[*]不能用于管理数组对象(用boost::share_array代替)
[*]它是线程安全的。
boost::shared_ptr的使用场景:

[*]避免对shared_ptr所管理的对象的直接内存管理操作,以免造成该对象的重释放
[*]shared_ptr并不能对循环引用的对象内存自动管理(这点是其它各种引用计数管理内存方式的通病)。
[*]不要构造一个临时的shared_ptr作为函数的参数。
[*]用于标准模板库的容器中
boost::shared_array<T>http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/shared_array.htm

shared_array用于确保能够正确的删除通过new[]分配的动态数组对象,与boost::scoped_array不同,shared_array具有提供拷贝构造和赋值运算,具有共享和转移所有权。并提供了比较运算符,可以被标准模板库中的容器使用。
因为它是通过引用计数实现,故对循环引用的实例将无法正确回收。
std::vector<boost::shared_ptr>是boost::shared_array的替代方案,后者虽然比前者具有更重的责任,但是比前者灵活的多。
boost::intrusive_ptr<T>http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/intrusive_ptr.html

intrusive_ptr一种“侵入式”的引用计数指针,它实际并不提供引用计数功能,而是要求被存储的对象自己实现引用计数功能,并提供intrusive_ptr_add_ref和intrusive_ptr_release函数接口供intrusive_ptr调用。如果编译器支持参数相关查找,可把这两个函数定义在其参数所在的命名空间,否则需定义在boost命名空间内。
有两种方法实现intrusive_ptr_add_ref和intrusive_ptr_release接口:


[*]自定义的类从boost提供的引用计数器基类boost::intrusive_ptr_base<T>继承
[*]类似com接口指针等,自己实现引用计数功能,并特例化intrusive_ptr_add_ref和intrusive_ptr_release这两个接口。
如果T*可以隐式转换为U*,那么intrusive_ptr<T>也可隐式转换为intrusive_ptr<U>。
使用boost::intrusive_ptr的场景:


[*]一些现有的框架或操作系统提供了具有嵌入式引用计数的对像,如com对象
[*]intrusive_ptr和其相应的原始指针指向的内存是一样的
[*]可以从任意T*类型的原始指针构造intrusive_ptr<T>
一般情况下,如果能使用boost::shared_ptr就不要使用boost::intrusive_ptr。


ztenv 发表于 2012-7-21 09:57:11

boost值得好好的学一下,C++最新标准有很多来自于boost
页: [1]
查看完整版本: boost笔记:智能指针--概述