标签:
文档:
http://www.boost.org/doc/libs/1_57_0/libs/smart_ptr/shared_ptr.htm
The shared_ptr
class template stores a pointer to a dynamically allocated object, typically with a C++ new-expression. The object pointed to is guaranteed to be deleted when the last shared_ptr
pointing to it is destroyed or reset.
Example:
shared_ptr<X> p1( new X ); shared_ptr<void> p2( new int(5) );
shared_ptr
deletes the exact pointer that has been passed at construction time, complete with its original type, regardless of the template parameter. In the second example above, when p2
is destroyed or reset, it will call delete
on the original int*
that has been passed to the constructor, even though p2
itself is of type shared_ptr<void>
and stores a pointer of type void*
.
Every shared_ptr
meets the CopyConstructible
, MoveConstructible
, CopyAssignable
and MoveAssignable
requirements of the C++ Standard Library, and can be used in standard library containers. Comparison operators are supplied so that shared_ptr
works with the standard library‘s associative containers.
Because the implementation uses reference counting, cycles of shared_ptr
instances will not be reclaimed. For example, if main()
holds a shared_ptr
to A
, which directly or indirectly holds a shared_ptr
back to A
, A
‘s use count will be 2. Destruction of the original shared_ptr
will leave A
dangling with a use count of 1. Use weak_ptr to "break cycles."
The class template is parameterized on T
, the type of the object pointed to. shared_ptr
and most of its member functions place no requirements on T
; it is allowed to be an incomplete type, or void
. Member functions that do place additional requirements (constructors, reset) are explicitly documented below.
shared_ptr<T>
can be implicitly converted to shared_ptr<U>
whenever T*
can be implicitly converted to U*
. In particular, shared_ptr<T>
is implicitly convertible to shared_ptr<T const>
, to shared_ptr<U>
where U
is an accessible base of T
, and to shared_ptr<void>
.
shared_ptr
is now part of the C++11 Standard, as std::shared_ptr
.
Starting with Boost release 1.53, shared_ptr
can be used to hold a pointer to a dynamically allocated array. This is accomplished by using an array type (T[]
or T[N]
) as the template parameter. There is almost no difference between using an unsized array, T[]
, and a sized array, T[N]
; the latter just enables operator[]
to perform a range check on the index.
Example:
shared_ptr<double[1024]> p1( new double[1024] ); shared_ptr<double[]> p2( new double[n] );
A simple guideline that nearly eliminates the possibility of memory leaks is: always use a named smart pointer variable to hold the result of new
. Every occurence of the new
keyword in the code should have the form:
shared_ptr<T> p(new Y);
It is, of course, acceptable to use another smart pointer in place of shared_ptr
above; having T
and Y
be the same type, or passing arguments to Y
‘s constructor is also OK.
If you observe this guideline, it naturally follows that you will have no explicit delete
statements; try/catch
constructs will be rare.
Avoid using unnamed shared_ptr
temporaries to save typing; to see why this is dangerous, consider this example:
void f(shared_ptr<int>, int); int g(); void ok() { shared_ptr<int> p( new int(2) ); f( p, g() ); } void bad() { f( shared_ptr<int>( new int(2) ), g() ); }
The function ok
follows the guideline to the letter, whereas bad
constructs the temporary shared_ptr
in place, admitting the possibility of a memory leak. Since function arguments are evaluated in unspecified order, it is possible for new int(2)
to be evaluated first, g()
second, and we may never get to the shared_ptr
constructor if g
throws an exception. See Herb Sutter‘s treatment (also here) of the issue for more information.
The exception safety problem described above may also be eliminated by using the make_shared
or allocate_shared
factory functions defined in boost/make_shared.hpp
. These factory functions also provide an efficiency benefit by consolidating allocations.
-------------------------------------------------------------------------------------------------------
boost::scoped_ptr虽然简单易用,但它不能共享所有权的特性却大大限制了其使用范围,而boost::shared_ptr可以解决这一局限。顾名思义,boost::shared_ptr是可以共享所有权的智能指针,首先让我们通过一个例子看看它的基本用法:
#include<iostream> #include<boost/shared_ptr.hpp> using namespace std; using boost::shared_ptr; class A { public: ~A(){ cout<<"destroy \n";} void do_sth(){cout<<"do somthing\n";} }; int main() { shared_ptr<A> a1(new A()); cout<<"the sample now has "<<a1.use_count()<<" references \n"; shared_ptr<A> a2=a1; cout<<"the sample now has "<<a1.use_count()<<" references \n"; a1.reset(); std::cout<<"After Reset sp1. The Sample now has "<<a2.use_count()<<" references\n"; a2.reset(); std::cout<<"After Reset sp2.\n"; }
root@iZ23onhpqvwZ:~/ms/boost# ./shared_ptr
the sample now has 1 references
the sample now has 2 references
After Reset sp1. The Sample now has 1 references
destroy
After Reset sp2.
可以看到,boost::shared_ptr指针sp1和sp2同时拥有了implementation对象的访问权限,且当sp1和sp2都释放对该对象的所有权时,其所管理的的对象的内存才被自动释放。在共享对象的访问权限同时,也实现了其内存的自动管理。
boost::shared_ptr的特点:
和前面介绍的boost::scoped_ptr相比,boost::shared_ptr可以共享对象的所有权,因此其使用范围基本上没有什么限制(还是有一些需要遵循的使用规则,下文中介绍),自然也可以使用在stl的容器中。另外它还是线程安全的,这点在多线程程序中也非常重要。
boost::shared_ptr的使用规则:
boost::shared_ptr并不是绝对安全,下面几条规则能使我们更加安全的使用boost::shared_ptr:
当函数g()抛异常的时候就会泄露了,这个是boost文档上特地注明的标准bad Practices。
---------------------
shared_ptr陷阱:
标签:
原文地址:http://www.cnblogs.com/youxin/p/4275289.html