boost::scoped_ptr<T>
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_array<T>
scoped_array用于确保能够正确地删除动态分配(new[])的数组对象。scoped_array与scoped_ptr均不能共享所有权,不能转移所有权。不同的是scoped_array提供了operator[]来模仿一个裸数组。
scoped_array是比普通的动态分配数组更好用。它处理了动态分配数组的生存期管理问题,就如scoped_ptr管理对象指针的生存期一样。只有当你需要确保数组的大小是固定的时候,才使用boost::scoped_array来替代std::vector。
boost::shared_ptr<T>
boost::shared_ptr的管理机制其实并不复杂,就是对所管理的对象进行了引用计数,当新增一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数加一;减少一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数减一,如果该对象的引用计数为0的时候,说明没有任何指针对其管理,才调用delete释放其所占的内存。
boost::shared_ptr的特点:
- 在内部维护一个引用计数器, 当有一个指针指向这块内存区域是引用计数+1, 反之-1, 如果没有任何指针指向这块区域,引用计数器为0,释放内存区域。
- 可以共享和转移所有权。
- 可以被标准库的容器所使用
- 不能用于管理数组对象(用boost::share_array代替)
- 它是线程安全的。
- 避免对shared_ptr所管理的对象的直接内存管理操作,以免造成该对象的重释放
- shared_ptr并不能对循环引用的对象内存自动管理(这点是其它各种引用计数管理内存方式的通病)。
- 不要构造一个临时的shared_ptr作为函数的参数。
- 用于标准模板库的容器中
boost::shared_array<T>
shared_array用于确保能够正确的删除通过new[]分配的动态数组对象,与boost::scoped_array不同,shared_array具有提供拷贝构造和赋值运算,具有共享和转移所有权。并提供了比较运算符,可以被标准模板库中的容器使用。
因为它是通过引用计数实现,故对循环引用的实例将无法正确回收。
std::vector<boost::shared_ptr>是boost::shared_array的替代方案,后者虽然比前者具有更重的责任,但是比前者灵活的多。
boost::intrusive_ptr<T>
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这两个接口。
使用boost::intrusive_ptr的场景:
- 一些现有的框架或操作系统提供了具有嵌入式引用计数的对像,如com对象
- intrusive_ptr和其相应的原始指针指向的内存是一样的
- 可以从任意T*类型的原始指针构造intrusive_ptr<T>