effective c++条款13-17 “以对象管理资源”之shared_ptr浅析
2014-12-01 15:48
405 查看
顾名思义,boost::shared_ptr是可以共享所有权的智能指针
模板类接口设计:注意shared_ptr的几种构造函数的差异
让我们通过一个例子看看它的基本用法:
该程序的输出结果如下:
The Sample now has 1 references
The Sample now has 2 references
After Reset sp1. The Sample now has 1 references
destroying implementation
After Reset sp2.
可以看到,boost::shared_ptr指针sp1和sp2同时拥有了implementation对象的访问权限,且当sp1和sp2都释放对该对象的所有权时,其所管理的的对象的内存才被自动释放。在共享对象的访问权限同时,也实现了其内存的自动管理。
boost::shared_ptr的内存管理机制:
boost::shared_ptr的管理机制其实并不复杂,就是对所管理的对象进行了引用计数,当新增一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数加一;减少一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数减一,如果该对象的引用计数为0的时候,说明没有任何指针对其管理,才调用delete释放其所占的内存。
上面的那个例子可以的图示如下:
sp1对implementation对象进行管理,其引用计数为1
增加sp2对implementation对象进行管理,其引用计数增加为2
sp1释放对implementation对象进行管理,其引用计数变为1
sp2释放对implementation对象进行管理,其引用计数变为0,该对象被自动删除
boost::shared_ptr的特点:
boost::shared_ptr可以共享对象的所有权,因此其使用范围基本上没有什么限制(还是有一些需要遵循的使用规则,下文中介绍),自然也可以使用在stl的容器中。另外它还是线程安全的,这点在多线程程序中也非常重要。
boost::shared_ptr的使用规则:
boost::shared_ptr并不是绝对安全,下面几条规则能使我们更加安全的使用boost::shared_ptr:
避免对shared_ptr所管理的对象的直接内存管理操作,以免造成该对象的重释放
shared_ptr并不能对循环引用的对象内存自动管理(这点是其它各种引用计数管理内存方式的通病)。
不要构造一个临时的shared_ptr作为函数的参数。
如下列代码则可能导致内存泄漏:
void test()
{
foo(boost::shared_ptr<implementation>(new implementation()),g());
}
正确的用法为:
void test()
{
boost::shared_ptr<implementation> sp (new implementation());
foo(sp,g());
}
模板类接口设计:注意shared_ptr的几种构造函数的差异
namespace boost { class bad_weak_ptr: public std::exception; template<class T> class weak_ptr; template<class T> class shared_ptr { public: typedef T element_type; shared_ptr(); // never throws template<class Y> explicit shared_ptr(Y * p); template<class Y, class D> shared_ptr(Y * p, D d); template<class Y, class D, class A> shared_ptr(Y * p, D d, A a); ~shared_ptr(); // never throws shared_ptr(shared_ptr const & r); // never throws template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p); // never throws template<class Y> explicit shared_ptr(weak_ptr<Y> const & r); template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r); shared_ptr & operator=(shared_ptr const & r); // never throws template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r); void reset(); // never throws template<class Y> void reset(Y * p); template<class Y, class D> void reset(Y * p, D d); template<class Y, class D, class A> void reset(Y * p, D d, A a); template<class Y> void reset(shared_ptr<Y> const & r, T * p); // never throws T & operator*() const; // never throws T * operator->() const; // never throws T * get() const; // never throws bool unique() const; // never throws long use_count() const; // never throws operator unspecified-bool-type() const; // never throws void swap(shared_ptr & b); // never throws }; template<class T, class U> bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws template<class T, class U> bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws template<class T, class U> bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws template<class T> T * get_pointer(shared_ptr<T> const & p); // never throws template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r); // never throws template<class E, class T, class Y> std::basic_ostream<E, T> & operator<<(std::basic_ostream<E, T> & os, shared_ptr<Y> const & p); template<class D, class T> D * get_deleter(shared_ptr<T> const & p); }
让我们通过一个例子看看它的基本用法:
#include <string> #include <iostream> #include <boost/shared_ptr.hpp> class implementation { public: ~implementation() { std::cout <<"destroying implementation\n"; } void do_something() { std::cout << "did something\n"; } }; void test() { boost::shared_ptr<implementation> sp1(new implementation()); std::cout<<"The Sample now has "<<sp1.use_count()<<" references\n"; boost::shared_ptr<implementation> sp2 = sp1; std::cout<<"The Sample now has "<<sp2.use_count()<<" references\n"; sp1.reset(); std::cout<<"After Reset sp1. The Sample now has "<<sp2.use_count()<<" references\n"; sp2.reset(); std::cout<<"After Reset sp2.\n"; } void main() { test(); }
该程序的输出结果如下:
The Sample now has 1 references
The Sample now has 2 references
After Reset sp1. The Sample now has 1 references
destroying implementation
After Reset sp2.
可以看到,boost::shared_ptr指针sp1和sp2同时拥有了implementation对象的访问权限,且当sp1和sp2都释放对该对象的所有权时,其所管理的的对象的内存才被自动释放。在共享对象的访问权限同时,也实现了其内存的自动管理。
boost::shared_ptr的内存管理机制:
boost::shared_ptr的管理机制其实并不复杂,就是对所管理的对象进行了引用计数,当新增一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数加一;减少一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数减一,如果该对象的引用计数为0的时候,说明没有任何指针对其管理,才调用delete释放其所占的内存。
上面的那个例子可以的图示如下:
sp1对implementation对象进行管理,其引用计数为1
增加sp2对implementation对象进行管理,其引用计数增加为2
sp1释放对implementation对象进行管理,其引用计数变为1
sp2释放对implementation对象进行管理,其引用计数变为0,该对象被自动删除
boost::shared_ptr的特点:
boost::shared_ptr可以共享对象的所有权,因此其使用范围基本上没有什么限制(还是有一些需要遵循的使用规则,下文中介绍),自然也可以使用在stl的容器中。另外它还是线程安全的,这点在多线程程序中也非常重要。
boost::shared_ptr的使用规则:
boost::shared_ptr并不是绝对安全,下面几条规则能使我们更加安全的使用boost::shared_ptr:
避免对shared_ptr所管理的对象的直接内存管理操作,以免造成该对象的重释放
shared_ptr并不能对循环引用的对象内存自动管理(这点是其它各种引用计数管理内存方式的通病)。
不要构造一个临时的shared_ptr作为函数的参数。
如下列代码则可能导致内存泄漏:
void test()
{
foo(boost::shared_ptr<implementation>(new implementation()),g());
}
正确的用法为:
void test()
{
boost::shared_ptr<implementation> sp (new implementation());
foo(sp,g());
}
相关文章推荐
- effective c++条款13-17 “以对象管理资源”之C++类型转换函数和构造函数
- effective c++条款13-17 “以对象管理资源”之RAII浅析
- effective c++条款13-17 “以对象管理资源”之auto_ptr源码分析
- Effective C++ 条款13 以对象管理资源
- Effective C++——》条款13:以对象管理资源
- Effective C++_笔记_条款13_以对象管理资源
- 条款13:以对象管理资源
- 条款13 以对象管理资源
- Effective C++:条款13:以对象管理资源
- 《Effective C++》学习笔记条款13 以对象管理资源
- 条款13:以对象管理资源
- 【Effective c++】条款13:以对象管理资源
- 《Effective C++》学习笔记条款13 以对象管理资源
- 条款13:以对象管理资源
- effective C++ 条款 13:以对象管理资源
- 条款13:以对象管理资源
- 3. 资源管理(条款:13-17)
- 条款13:以对象管理资源
- Effective C++ Item 13 以对象管理资源
- 《Effective C++ 3》03 资源管理 条款:13-17