2000-07-27 14:27:00 +00:00
|
|
|
|
<html>
|
|
|
|
|
|
|
|
|
|
<head>
|
|
|
|
|
<title>shared_ptr</title>
|
2002-01-11 16:15:09 +00:00
|
|
|
|
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
2000-07-27 14:27:00 +00:00
|
|
|
|
<meta name="ProgId" content="FrontPage.Editor.Document">
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
<body bgcolor="#FFFFFF" text="#000000">
|
|
|
|
|
|
2002-01-11 16:15:09 +00:00
|
|
|
|
<h1>
|
|
|
|
|
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" width="277" height="86">Class
|
2000-07-27 14:27:00 +00:00
|
|
|
|
<a name="shared_ptr">shared_ptr</a></h1>
|
2001-07-12 19:51:53 +00:00
|
|
|
|
<p><a href="#Introduction">Introduction<br>
|
|
|
|
|
Synopsis</a><br>
|
|
|
|
|
<a href="#Members">Members</a><br>
|
|
|
|
|
<a href="#shared_ptr_example">Example</a><br>
|
|
|
|
|
<a href="#Handle/Body">Handle/Body Idiom</a><br>
|
2002-01-11 16:15:09 +00:00
|
|
|
|
<a href="#FAQ">Frequently Asked Questions</a><br>
|
|
|
|
|
<a href="smarttests.htm">Smart Pointer Timings</a></p>
|
2001-07-12 19:51:53 +00:00
|
|
|
|
<h2><a name="Introduction">Introduction</a></h2>
|
2000-07-27 14:27:00 +00:00
|
|
|
|
<p>Class <strong>shared_ptr</strong> stores a pointer to a dynamically allocated
|
|
|
|
|
object. (Dynamically allocated objects are allocated with the C++ <tt>new</tt>
|
|
|
|
|
expression.) The object pointed to is guaranteed to be deleted when
|
|
|
|
|
the last <strong>shared_ptr</strong> pointing to it is deleted or reset.
|
|
|
|
|
See <a href="#shared_ptr_example">example</a>.</p>
|
|
|
|
|
<p>Class<strong> shared_ptr</strong> meets the <strong>CopyConstuctible</strong>
|
|
|
|
|
and <strong>Assignable</strong> requirements of the C++ Standard Library, and so
|
|
|
|
|
can be used in C++ Standard Library containers. A specialization of std::
|
|
|
|
|
less< > for boost::shared_ptr<Y> is supplied so that <strong>
|
|
|
|
|
shared_ptr</strong> works by default for Standard Library's Associative
|
|
|
|
|
Container Compare template parameter. For compilers not supporting partial
|
|
|
|
|
specialization, the user must explicitly pass the less<> functor.</p>
|
|
|
|
|
<p>Class<strong> shared_ptr</strong> cannot correctly hold a pointer to a
|
|
|
|
|
dynamically allocated array. See <a href="shared_array.htm"><strong>shared_array</strong></a>
|
|
|
|
|
for that usage.</p>
|
|
|
|
|
<p>Class<strong> shared_ptr</strong> will not work correctly with cyclic data
|
|
|
|
|
structures. For example, if main() holds a shared_ptr to object A, which
|
|
|
|
|
directly or indirectly holds a shared_ptr back to object A, then object A's
|
|
|
|
|
use_count() will be 2, and destruction of the main() shared_ptr will leave
|
|
|
|
|
object A dangling with a use_count() of 1.</p>
|
|
|
|
|
<p>The class is a template parameterized on <tt>T</tt>, the type of the object
|
|
|
|
|
pointed to. <tt>T</tt> must meet the smart pointer <a href="smart_ptr.htm#Common requirements">Common
|
|
|
|
|
requirements</a>.</p>
|
2001-07-12 19:51:53 +00:00
|
|
|
|
<h2>Class shared_ptr <a name="Synopsis"> Synopsis</a></h2>
|
2001-05-24 18:42:25 +00:00
|
|
|
|
<pre>#include <<a href="../../boost/smart_ptr.hpp">boost/smart_ptr.hpp</a>>
|
2000-07-27 14:27:00 +00:00
|
|
|
|
namespace boost {
|
|
|
|
|
|
|
|
|
|
template<typename T> class shared_ptr {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef T <a href="#shared_ptr_element_type">element_type</a>;
|
|
|
|
|
|
|
|
|
|
explicit <a href="#shared_ptr_ctor">shared_ptr</a>( T* p=0 );
|
|
|
|
|
<strong> </strong><a href="#shared_ptr_~shared_ptr">~shared_ptr</a>();
|
|
|
|
|
|
|
|
|
|
<a href="#shared_ptr_ctor">shared_ptr</a>( const shared_ptr& );
|
|
|
|
|
template<typename Y>
|
|
|
|
|
<a href="#shared_ptr_ctor">shared_ptr</a>(const shared_ptr<Y>& r); // never throws
|
|
|
|
|
template<typename Y>
|
|
|
|
|
<a href="#shared_ptr_ctor">shared_ptr</a>(std::auto_ptr<Y>& r);
|
|
|
|
|
|
|
|
|
|
shared_ptr& <a href="#shared_ptr_operator=">operator=</a>( const shared_ptr& ); // never throws
|
|
|
|
|
template<typename Y>
|
|
|
|
|
shared_ptr& <a href="#shared_ptr_operator=">operator=</a>(const shared_ptr<Y>& r); // never throws
|
|
|
|
|
template<typename Y>
|
|
|
|
|
shared_ptr& <a href="#shared_ptr_operator=">operator=</a>(std::auto_ptr<Y>& r);
|
|
|
|
|
|
|
|
|
|
void <a href="#shared_ptr_reset">reset</a>( T* p=0 );
|
|
|
|
|
|
|
|
|
|
T& <a href="#shared_ptr_operator*">operator*</a>() const; // never throws
|
|
|
|
|
T* <a href="#shared_ptr_operator->">operator-></a>() const; // never throws
|
|
|
|
|
T* <a href="#shared_ptr_get">get</a>() const; // never throws
|
|
|
|
|
|
|
|
|
|
long <a href="#shared_ptr_use_count">use_count</a>() const; // never throws
|
|
|
|
|
bool <a href="#shared_ptr_unique">unique</a>() const; // never throws
|
|
|
|
|
|
|
|
|
|
void <a href="#shared_ptr_swap">swap</a>( shared_ptr<T>& other ) throw()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<typename T, typename U>
|
|
|
|
|
inline bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b)
|
|
|
|
|
{ return a.get() == b.get(); }
|
|
|
|
|
|
|
|
|
|
template<typename T, typename U>
|
|
|
|
|
inline bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b)
|
|
|
|
|
{ return a.get() != b.get(); }
|
|
|
|
|
}</pre>
|
|
|
|
|
<pre>namespace std {
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline void swap(boost::shared_ptr<T>& a, boost::shared_ptr<T>& b)
|
|
|
|
|
{ a.swap(b); }
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
struct less< boost::shared_ptr<T> >
|
|
|
|
|
: binary_function<boost::shared_ptr<T>, boost::shared_ptr<T>, bool>
|
|
|
|
|
{
|
|
|
|
|
bool operator()(const boost::shared_ptr<T>& a,
|
|
|
|
|
const boost::shared_ptr<T>& b) const
|
|
|
|
|
{ return less<T*>()(a.get(),b.get()); }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace std </pre>
|
|
|
|
|
<p>Specialization of std::swap uses the fast, non-throwing swap that's provided
|
|
|
|
|
as a member function instead of using the default algorithm which creates a
|
|
|
|
|
temporary and uses assignment.<br>
|
|
|
|
|
<br>
|
|
|
|
|
Specialization of std::less allows use of shared pointers as keys in C++
|
|
|
|
|
Standard Library associative collections.<br>
|
|
|
|
|
<br>
|
|
|
|
|
The std::less specializations use std::less<T*> to perform the
|
|
|
|
|
comparison. This insures that pointers are handled correctly, since the
|
|
|
|
|
standard mandates that relational operations on pointers are unspecified (5.9 [expr.rel]
|
|
|
|
|
paragraph 2) but std::less<> on pointers is well-defined (20.3.3 [lib.comparisons]
|
|
|
|
|
paragraph 8).<br>
|
|
|
|
|
<br>
|
|
|
|
|
It's still a controversial question whether supplying only std::less is better
|
|
|
|
|
than supplying a full range of comparison operators (<, >, <=, >=).</p>
|
|
|
|
|
<p>The current implementation does not supply the specializations if the macro
|
|
|
|
|
name BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION is defined.</p>
|
|
|
|
|
<p>The current implementation does not supply the member template functions if
|
|
|
|
|
the macro name BOOST_NO_MEMBER_TEMPLATES is defined.</p>
|
2001-07-12 19:51:53 +00:00
|
|
|
|
<h2>Class shared_ptr <a name="Members"> Members</a></h2>
|
2000-07-27 14:27:00 +00:00
|
|
|
|
<h3>shared_ptr <a name="shared_ptr_element_type">element_type</a></h3>
|
|
|
|
|
<pre>typedef T element_type;</pre>
|
|
|
|
|
<p>Provides the type of the stored pointer.</p>
|
|
|
|
|
<h3><a name="shared_ptr_ctor">shared_ptr constructors</a></h3>
|
|
|
|
|
<pre>explicit shared_ptr( T* p=0 );</pre>
|
|
|
|
|
<p>Constructs a <strong>shared_ptr</strong>, storing a copy of <tt>p</tt>, which
|
|
|
|
|
must have been allocated via a C++ <tt>new</tt> expression or be 0. Afterwards, <strong>use_count()</strong>
|
|
|
|
|
is 1 (even if p==0; see <a href="#shared_ptr_~shared_ptr">~shared_ptr</a>).</p>
|
|
|
|
|
<p>The only exception which may be thrown by this constructor is <tt>std::bad_alloc</tt>.
|
|
|
|
|
If an exception is thrown, <tt>delete p</tt> is called.</p>
|
|
|
|
|
<pre>shared_ptr( const shared_ptr& r); // never throws
|
|
|
|
|
template<typename Y>
|
|
|
|
|
shared_ptr(const shared_ptr<Y>& r); // never throws
|
|
|
|
|
template<typename Y>
|
|
|
|
|
shared_ptr(std::auto_ptr<Y>& r);</pre>
|
|
|
|
|
<p>Constructs a <strong>shared_ptr</strong>, as if by storing a copy of the
|
|
|
|
|
pointer stored in <strong>r</strong>. Afterwards, <strong>use_count()</strong>
|
|
|
|
|
for all copies is 1 more than the initial <strong>r.use_count()</strong>, or 1
|
|
|
|
|
in the <strong>auto_ptr</strong> case. In the <strong>auto_ptr</strong> case, <strong>r.release()</strong>
|
|
|
|
|
is called.</p>
|
|
|
|
|
<p>The only exception which may be thrown by the constructor from <strong>auto_ptr</strong>
|
|
|
|
|
is <tt>std::bad_alloc</tt>. If an exception is thrown, that
|
|
|
|
|
constructor has no effect.</p>
|
|
|
|
|
<h3><a name="shared_ptr_~shared_ptr">shared_ptr destructor</a></h3>
|
|
|
|
|
<pre>~shared_ptr();</pre>
|
|
|
|
|
<p>If <strong>use_count()</strong> == 1, deletes the object pointed to by the
|
|
|
|
|
stored pointer. Otherwise, <strong>use_count()</strong> for any remaining
|
|
|
|
|
copies is decremented by 1. Note that in C++ <tt>delete</tt> on a pointer
|
|
|
|
|
with a value of 0 is harmless.</p>
|
|
|
|
|
<p>Does not throw exceptions.</p>
|
|
|
|
|
<h3>shared_ptr <a name="shared_ptr_operator=">operator=</a></h3>
|
|
|
|
|
<pre>shared_ptr& operator=( const shared_ptr& r);
|
|
|
|
|
template<typename Y>
|
|
|
|
|
shared_ptr& operator=(const shared_ptr<Y>& r);
|
|
|
|
|
template<typename Y>
|
|
|
|
|
shared_ptr& operator=(std::auto_ptr<Y>& r);</pre>
|
|
|
|
|
<p>First, if <strong>use_count()</strong> == 1, deletes the object pointed to by
|
|
|
|
|
the stored pointer. Otherwise, <strong>use_count()</strong> for any
|
|
|
|
|
remaining copies is decremented by 1. Note that in C++ <tt>delete</tt> on
|
|
|
|
|
a pointer with a value of 0 is harmless.</p>
|
|
|
|
|
<p>Then replaces the contents of <strong>this</strong>, as if by storing a copy
|
|
|
|
|
of the pointer stored in <strong>r</strong>. Afterwards, <strong>use_count()</strong>
|
|
|
|
|
for all copies is 1 more than the initial <strong>r.use_count()</strong>, or 1
|
|
|
|
|
in the <strong>auto_ptr</strong> case. In the <strong>auto_ptr</strong> case, <strong>r.release()</strong>
|
|
|
|
|
is called.</p>
|
|
|
|
|
<p>The first two forms of <tt>operator=</tt> above do not throw exceptions.</p>
|
|
|
|
|
<p>The only exception which may be thrown by the <strong>auto_ptr</strong> form
|
|
|
|
|
is <tt>std::bad_alloc</tt>. If an exception is thrown, the function
|
|
|
|
|
has no effect.</p>
|
|
|
|
|
<h3>shared_ptr <a name="shared_ptr_reset">reset</a></h3>
|
|
|
|
|
<pre>void reset( T* p=0 );</pre>
|
|
|
|
|
<p>First, if <strong>use_count()</strong> == 1, deletes the object pointed to by
|
|
|
|
|
the stored pointer. Otherwise, <strong>use_count()</strong> for any
|
|
|
|
|
remaining copies is decremented by 1. </p>
|
|
|
|
|
<p>Then replaces the contents of <strong>this</strong>, as if by storing a copy
|
|
|
|
|
of <strong>p</strong>, which must have been allocated via a C++ <tt>new</tt>
|
|
|
|
|
expression or be 0. Afterwards, <strong>use_count()</strong> is 1 (even if p==0;
|
|
|
|
|
see <a href="#shared_ptr_~shared_ptr">~shared_ptr</a>). Note that in C++ <tt>delete</tt>
|
|
|
|
|
on a pointer with a value of 0 is harmless.</p>
|
|
|
|
|
<p>The only exception which may be thrown is <tt>std::bad_alloc</tt>. If
|
|
|
|
|
an exception is thrown, <tt>delete p</tt> is called.</p>
|
|
|
|
|
<h3>shared_ptr <a name="shared_ptr_operator*">operator*</a></h3>
|
|
|
|
|
<pre>T& operator*() const; // never throws</pre>
|
|
|
|
|
<p>Returns a reference to the object pointed to by the stored pointer.</p>
|
|
|
|
|
<h3>shared_ptr <a name="shared_ptr_operator->">operator-></a> and <a name="shared_ptr_get">get</a></h3>
|
|
|
|
|
<pre>T* operator->() const; // never throws
|
|
|
|
|
T* get() const; // never throws</pre>
|
2001-05-24 18:42:25 +00:00
|
|
|
|
<p><b>T</b> is not required by get() to be a complete type . See <a href="smart_ptr.htm#Common requirements">Common Requirements</a>.</p>
|
2000-07-27 14:27:00 +00:00
|
|
|
|
<p>Both return the stored pointer.</p>
|
|
|
|
|
<h3>shared_ptr<a name="shared_ptr_use_count"> use_count</a></h3>
|
|
|
|
|
<p><tt>long use_count() const; // never throws</tt></p>
|
2001-05-24 18:42:25 +00:00
|
|
|
|
<p><b>T</b> is not required be a complete type.
|
2001-05-22 18:58:21 +00:00
|
|
|
|
See <a href="smart_ptr.htm#Common requirements">Common Requirements</a>.</p>
|
2000-07-27 14:27:00 +00:00
|
|
|
|
<p>Returns the number of <strong>shared_ptrs</strong> sharing ownership of the
|
|
|
|
|
stored pointer.</p>
|
|
|
|
|
<h3>shared_ptr <a name="shared_ptr_unique">unique</a></h3>
|
|
|
|
|
<p><tt>bool unique() const; // never throws</tt></p>
|
2001-05-24 18:42:25 +00:00
|
|
|
|
<p><b>T</b> is not required be a complete type.
|
2001-05-22 18:58:21 +00:00
|
|
|
|
See <a href="smart_ptr.htm#Common requirements">Common Requirements</a>.</p>
|
2000-07-27 14:27:00 +00:00
|
|
|
|
<p>Returns <strong>use_count()</strong> == 1.</p>
|
|
|
|
|
<h3><a name="shared_ptr_swap">shared_ptr swap</a></h3>
|
|
|
|
|
<p><code>void swap( shared_ptr<T>& other ) throw()</code></p>
|
2001-05-24 18:42:25 +00:00
|
|
|
|
<p><b>T</b> is not required be a complete type.
|
2001-05-22 18:58:21 +00:00
|
|
|
|
See <a href="smart_ptr.htm#Common requirements">Common Requirements</a>.</p>
|
2000-07-27 14:27:00 +00:00
|
|
|
|
<p>Swaps the two smart pointers, as if by std::swap.</p>
|
|
|
|
|
<h2>Class <a name="shared_ptr_example">shared_ptr example</a></h2>
|
2001-05-21 14:58:07 +00:00
|
|
|
|
<p>See <a href="shared_ptr_example.cpp"> shared_ptr_example.cpp</a> for a complete example program.</p>
|
|
|
|
|
<p>This program builds a std::vector and std::set of FooPtr's.</p>
|
|
|
|
|
<p>Note that after the two containers have been populated, some of the FooPtr objects
|
|
|
|
|
will have use_count()==1 rather than use_count()==2, since foo_set is a std::set
|
2001-05-22 18:58:21 +00:00
|
|
|
|
rather than a std::multiset, and thus does not contain duplicate entries. Furthermore, use_count() may be even higher
|
2001-05-21 14:58:07 +00:00
|
|
|
|
at various times while push_back() and insert() container operations are performed.
|
2001-02-09 14:39:43 +00:00
|
|
|
|
More complicated yet, the container operations may throw exceptions under a
|
|
|
|
|
variety of circumstances. Without using a smart pointer, memory and
|
|
|
|
|
exception management would be a nightmare.</p>
|
2001-05-24 18:42:25 +00:00
|
|
|
|
<h2><a name="Handle/Body">Handle/Body</a> Idiom</h2>
|
|
|
|
|
<p>One common usage of <b>shared_ptr</b> is to implement a handle/body (also
|
|
|
|
|
called pimpl) idiom which avoids exposing the body (implementation) in the header
|
|
|
|
|
file.</p>
|
|
|
|
|
<p>The <a href="shared_ptr_example2_test.cpp">shared_ptr_example2_test.cpp</a>
|
|
|
|
|
sample program includes a header file, <a href="shared_ptr_example2.hpp">shared_ptr_example2.hpp</a>,
|
|
|
|
|
which uses a <b>shared_ptr<></b> to an incomplete type to hide the
|
|
|
|
|
implementation. The
|
|
|
|
|
instantiation of member functions which require a complete type occurs in the <a href="shared_ptr_example2.cpp">shared_ptr_example2.cpp</a>
|
|
|
|
|
implementation file.</p>
|
2001-07-12 19:51:53 +00:00
|
|
|
|
<h2><a name="FAQ">Frequently Asked Questions</a></h2>
|
2001-07-13 14:07:08 +00:00
|
|
|
|
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> have template parameters supplying
|
2001-05-24 18:42:25 +00:00
|
|
|
|
traits or policies to allow extensive user customization?<br>
|
2001-07-13 14:07:08 +00:00
|
|
|
|
<b>A.</b> Parameterization discourages users. <b>Shared_ptr</b> is
|
2001-05-24 18:42:25 +00:00
|
|
|
|
carefully crafted to meet common needs without extensive parameterization.
|
|
|
|
|
Someday a highly configurable smart pointer may be invented that is also very
|
|
|
|
|
easy to use and very hard to misuse. Until then, <b>shared_ptr</b> is the
|
2001-07-12 19:51:53 +00:00
|
|
|
|
smart pointer of choice for a wide range of applications. (Those
|
|
|
|
|
interested in policy based smart pointers should read <a href="http://cseng.aw.com/book/0,,0201704315,00.html">Modern
|
|
|
|
|
C++ Design</a> by Andrei Alexandrescu.)</p>
|
2001-07-13 14:07:08 +00:00
|
|
|
|
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> use a linked list implementation?<br>
|
|
|
|
|
<b>A.</b> A linked list implementation does not offer enough advantages to
|
2001-07-12 19:51:53 +00:00
|
|
|
|
offset the added cost of an extra pointer. See <a href="smarttests.htm">timings</a>
|
|
|
|
|
page.</p>
|
2001-07-13 14:07:08 +00:00
|
|
|
|
<p><b>Q.</b> Why don't <b>shared_ptr</b> (and the other Boost smart pointers)
|
2001-05-24 18:42:25 +00:00
|
|
|
|
supply an automatic conversion to <b>T*</b>?<br>
|
2001-07-13 14:07:08 +00:00
|
|
|
|
<b>A.</b> Automatic conversion is believed to be too error prone.</p>
|
|
|
|
|
<p><b>Q.</b> Why does <b>shared_ptr</b> supply use_count()?<br>
|
|
|
|
|
<b>A.</b> As an aid to writing test cases and debugging displays. One of the
|
|
|
|
|
progenitors had use_count(), and it was useful in tracking down bugs in a
|
|
|
|
|
complex project that turned out to have cyclic-dependencies.</p>
|
2001-07-13 16:32:34 +00:00
|
|
|
|
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> specify complexity requirements?<br>
|
|
|
|
|
<b>A.</b> Because complexity limit implementors and complicate the specification without apparent benefit to
|
|
|
|
|
<b>shared_ptr</b> users. For example, error-checking implementations might become non-conforming if they
|
|
|
|
|
had to meet stringent complexity requirements.</p>
|
|
|
|
|
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> provide (your pet feature here)?<br>
|
|
|
|
|
<b>A.</b> Because (your pet feature here) would mandate a reference counted (or a link-list, or ...) implementation. This is not the intent.
|
|
|
|
|
[Provided by Peter Dimov]<br>
|
|
|
|
|
</p>
|
2000-07-27 14:27:00 +00:00
|
|
|
|
<hr>
|
2002-01-11 16:15:09 +00:00
|
|
|
|
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->11 January, 2002<!--webbot bot="Timestamp" i-checksum="38439" endspan -->
|
2001-02-10 12:47:02 +00:00
|
|
|
|
</p>
|
2000-07-27 14:27:00 +00:00
|
|
|
|
<p><EFBFBD> Copyright Greg Colvin and Beman Dawes 1999. Permission to copy, use,
|
|
|
|
|
modify, sell and distribute this document is granted provided this copyright
|
|
|
|
|
notice appears in all copies. This document is provided "as is"
|
|
|
|
|
without express or implied warranty, and with no claim as to its suitability for
|
|
|
|
|
any purpose.</p>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
|
2002-01-11 16:15:09 +00:00
|
|
|
|
</html>
|