Revised to match the style of the C++ standard.

[SVN r12806]
This commit is contained in:
Peter Dimov
2002-02-14 17:12:07 +00:00
parent 6c5d296722
commit 309e6dd82e

View File

@ -1,376 +1,423 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>shared_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">shared_ptr
class template</h1>
<p><A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
<A href="#Members">Members</A><br>
<A href="#functions">Free Functions</A><br>
<A href="#example">Example</A><br>
<A href="#Handle/Body">Handle/Body Idiom</A><br>
<A href="#FAQ">Frequently Asked Questions</A><br>
<A href="smarttests.htm">Smart Pointer Timings</A></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <b>shared_ptr</b> class template stores a pointer to a dynamically allocated
object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.)
The object pointed to is guaranteed to be deleted when the last <b>shared_ptr</b>
pointing to it is destroyed or reset. See the <A href="#example">example</A>.</p>
<p>Every <b>shared_ptr</b> meets the <b>CopyConstructible</b> and <b>Assignable</b>
requirements of the C++ Standard Library, and so can be used in standard
library containers. Comparison operators are supplied so that <b>shared_ptr</b>
works with the standard library's associative containers.</p>
<p>Normally, a <b>shared_ptr</b> cannot correctly hold a pointer to a dynamically
allocated array. See <A href="shared_array.htm"><b>shared_array</b></A> for
that usage.</p>
<p>Because the implementation uses reference counting, <b>shared_ptr</b> will not
work correctly with cyclic data structures. For example, if <b>main()</b> holds
a <b>shared_ptr</b> to <b>A</b>, which directly or indirectly holds a <b>shared_ptr</b>
back to <b>A</b>, <b>A</b>'s use count will be 2. Destruction of the original <b>shared_ptr</b>
will leave <b>A</b> dangling with a use count of 1.</p>
<p>The class template is parameterized on <b>T</b>, the type of the object pointed
to. <b>T</b> must meet the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>. <b>T</b> may be <b>void</b>, but in that case,
either an explicit delete function must be passed in, or the pointed-to object
must have a trivial destructor.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>shared_ptr</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">shared_ptr class template</h1>
<p><a href="#Introduction">Introduction</a><br>
<a href="#Synopsis">Synopsis</a><br>
<a href="#Members">Members</a><br>
<a href="#functions">Free Functions</a><br>
<a href="#example">Example</a><br>
<a href="#Handle/Body">Handle/Body Idiom</a><br>
<a href="#FAQ">Frequently Asked Questions</a><br>
<a href="smarttests.htm">Smart Pointer Timings</a></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <b>shared_ptr</b> class template stores a pointer to a dynamically allocated
object. (Dynamically allocated objects are allocated with the C++ <b>new</b>
expression.) The object pointed to is guaranteed to be deleted when
the last <b>shared_ptr</b> pointing to it is destroyed or reset.
See the <a href="#example">example</a>.</p>
<p>Every <b>shared_ptr</b> meets the <b>CopyConstructible</b>
and <b>Assignable</b> requirements of the C++ Standard Library, and so
can be used in standard library containers. Comparison operators
are supplied so that <b>shared_ptr</b> works with
the standard library's associative containers.</p>
<p>Normally, a <b>shared_ptr</b> cannot correctly hold a pointer to a
dynamically allocated array. See <a href="shared_array.htm"><b>shared_array</b></a>
for that usage.</p>
<p>Because the implementation uses reference counting, <b>shared_ptr</b> will not work
correctly with cyclic data structures. For example, if <b>main()</b> holds a <b>shared_ptr</b>
to <b>A</b>, which directly or indirectly holds a <b>shared_ptr</b> back to <b>A</b>,
<b>A</b>'s use count will be 2. Destruction of the original <b>shared_ptr</b>
will leave <b>A</b> dangling with a use count of 1.</p>
<p>The class template is parameterized on <b>T</b>, the type of the object
pointed to. <b>T</b> must meet the smart pointer
<a href="smart_ptr.htm#Common requirements">common requirements</a>.
<b>T</b> may be <b>void</b>, but in that case, either an explicit delete
function must be passed in, or the pointed-to object must have a trivial destructor.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;typename T&gt; class <A href="weak_ptr.htm" >weak_ptr</A>;
template&lt;typename T&gt; class shared_ptr {
public:
typedef T <a href="#element_type">element_type</a>;
typedef T <A href="#element_type" >element_type</A>;
explicit <a href="#constructors">shared_ptr</a>(T * p = 0);
template&lt;typename D&gt; <a href="#constructors">shared_ptr</a>(T * p, D d);
<a href="#destructor">~shared_ptr</a>(); // never throws
explicit <A href="#constructors" >shared_ptr</A>(T * p = 0);
template&lt;typename D&gt; <A href="#constructors" >shared_ptr</A>(T * p, D d);
<A href="#destructor" >~shared_ptr</A>(); // never throws
<a href="#constructors">shared_ptr</a>(shared_ptr const &amp; r); // never throws
template&lt;typename Y&gt; <a href="#constructors">shared_ptr</a>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;typename Y&gt; <a href="#constructors">shared_ptr</a>(std::auto_ptr&lt;Y&gt; &amp; r);
<A href="#constructors" >shared_ptr</A>(shared_ptr const &amp; r); // never throws
template&lt;typename Y&gt; <A href="#constructors" >shared_ptr</A>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
<A href="#constructors" >shared_ptr</A>(<A href="weak_ptr.htm" >weak_ptr</A> const &amp; r);
template&lt;typename Y&gt; <A href="#constructors" >shared_ptr</A>(std::auto_ptr&lt;Y&gt; &amp; r);
shared_ptr &amp; <a href="#assignment">operator=</a>(shared_ptr const &amp; r); // never throws
template&lt;typename Y&gt; shared_ptr &amp; <a href="#assignment">operator=</a>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;typename Y&gt; shared_ptr &amp; <a href="#assignment">operator=</a>(std::auto_ptr&lt;Y&gt; &amp; r);
shared_ptr &amp; <A href="#assignment" >operator=</A>(shared_ptr const &amp; r); // never throws
template&lt;typename Y&gt; shared_ptr &amp; <A href="#assignment" >operator=</A>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;typename Y&gt; shared_ptr &amp; <A href="#assignment" >operator=</A>(std::auto_ptr&lt;Y&gt; &amp; r);
void <a href="#reset">reset</a>(T * p = 0);
template&lt;typename D&gt; void <a href="#reset">reset</a>(T * p, D d);
void <A href="#reset" >reset</A>(T * p = 0);
template&lt;typename D&gt; void <A href="#reset" >reset</A>(T * p, D d);
T &amp; <a href="#indirection">operator*</a>() const; // never throws
T * <a href="#indirection">operator-&gt;</a>() const; // never throws
T * <a href="#get">get</a>() const; // never throws
T &amp; <A href="#indirection" >operator*</A>() const; // never throws
T * <A href="#indirection" >operator-&gt;</A>() const; // never throws
T * <A href="#get" >get</A>() const; // never throws
bool <a href="#unique">unique</a>() const; // never throws
long <a href="#use_count">use_count</a>() const; // never throws
bool <A href="#unique" >unique</A>() const; // never throws
long <A href="#use_count" >use_count</A>() const; // never throws
void <a href="#swap">swap</a>(shared_ptr&lt;T&gt; &amp; b); // never throws
void <A href="#swap" >swap</A>(shared_ptr&lt;T&gt; &amp; b); // never throws
};
template&lt;typename T, typename U&gt;
bool <a href="#comparison">operator==</a>(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws
bool <A href="#comparison" >operator==</A>(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;typename T, typename U&gt;
bool <a href="#comparison">operator!=</a>(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws
bool <A href="#comparison" >operator!=</A>(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;typename T&gt;
bool <a href="#comparison">operator&lt;</a>(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;T&gt; const &amp; b); // never throws
bool <A href="#comparison" >operator&lt;</A>(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;T&gt; const &amp; b); // never throws
template&lt;typename T&gt; void <a href="#free-swap">swap</a>(shared_ptr&lt;T&gt; &amp; a, shared_ptr&lt;T&gt; &amp; b); // never throws
template&lt;typename T&gt; void <A href="#free-swap" >swap</A>(shared_ptr&lt;T&gt; &amp; a, shared_ptr&lt;T&gt; &amp; b); // never throws
template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt <a href="#shared_static_cast">shared_static_cast</a>(shared_ptr&lt;U&gt; const &amp; r); // never throws
shared_ptr&lt;T&gt; <A href="#shared_static_cast" >shared_static_cast</A>(shared_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt <a href="#shared_dynamic_cast">shared_dynamic_cast</a>(shared_ptr&lt;U&gt; const &amp; r);
shared_ptr&lt;T&gt; <A href="#shared_dynamic_cast" >shared_dynamic_cast</A>(shared_ptr&lt;U&gt; const &amp; r);
template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt <a href="#shared_polymorphic_cast">shared_polymorphic_cast</a>(shared_ptr&lt;U&gt; const &amp; r);
shared_ptr&lt;T&gt; <A href="#shared_polymorphic_cast" >shared_polymorphic_cast</A>(shared_ptr&lt;U&gt; const &amp; r);
template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt <a href="#shared_polymorphic_downcast">shared_polymorphic_downcast</a>(shared_ptr&lt;U&gt; const &amp; r); // never throws
shared_ptr&lt;T&gt; <A href="#shared_polymorphic_downcast" >shared_polymorphic_downcast</A>(shared_ptr&lt;U&gt; const &amp; r); // never throws
}</pre>
<h2><a name="Members">Members</a></h2>
<h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre>
<p>Provides the type of the stored pointer.</p>
<h3><a name="constructors">constructors</a></h3>
<pre>explicit shared_ptr(T * p = 0);</pre>
<p>Constructs a <b>shared_ptr</b>, storing a copy of <b>p</b>, which
must be a pointer to an object that was allocated via a C++ <b>new</b> expression or be 0.
Afterwards, the <a href="#use_count">use count</a> is 1 (even if p == 0; see <a href="#destructor">~shared_ptr</a>).
The only exception which may be thrown by this constructor is <b>std::bad_alloc</b>.
If an exception is thrown, <b>delete p</b> is called.</p>
<pre>template&lt;typename D&gt; shared_ptr(T * p, D d);</pre>
<p>Constructs a <b>shared_ptr</b>, storing a copy of <b>p</b> and of <b>d</b>.
Afterwards, the <a href="#use_count">use count</a> is 1.
<b>D</b>'s copy constructor and destructor must not throw.
When the the time comes to delete the object pointed to by <b>p</b>, the object
<b>d</b> is used in the statement <b>d(p)</b>. Invoking the object <b>d</b> with
parameter <b>p</b> in this way must not throw.
The only exception which may be thrown by this constructor is <b>std::bad_alloc</b>.
If an exception is thrown, <b>d(p)</b> is called.</p>
<pre>shared_ptr(shared_ptr const &amp; r); // never throws
template&lt;typename Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;typename Y&gt; shared_ptr(std::auto_ptr&lt;Y&gt; &amp; r);</pre>
<p>Constructs a <b>shared_ptr</b>, as if by storing a copy of the
pointer stored in <b>r</b>. Afterwards, the <a href="#use_count">use count</a>
for all copies is 1 more than the initial use count, or 1
in the <b>auto_ptr</b> case. In the <b>auto_ptr</b> case, <b>r.release()</b>
is called.
The only exception which may be thrown is <b>std::bad_alloc</b>,
which may be thrown during construction from <b>auto_ptr</b>.
If an exception is thrown, the constructor has no effect.</p>
<h3><a name="destructor">destructor</a></h3>
<pre>~shared_ptr(); // never throws</pre>
<p>Decrements the <a href="#use_count">use count</a>. Then, if the use count is 0,
deletes the object pointed to by the stored pointer.
Note that <b>delete</b> on a pointer with a value of 0 is harmless.
<b>T</b> need not be a complete type.
The guarantee that this does not throw exceptions depends on the requirement that the
deleted object's destructor does not throw exceptions.
See the smart pointer <a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
<h3><a name="operator=">assignment</a></h3>
<pre>shared_ptr &amp; <a href="#assignment">operator=</a>(shared_ptr const &amp; r); // never throws
template&lt;typename Y&gt; shared_ptr &amp; <a href="#assignment">operator=</a>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;typename Y&gt; shared_ptr &amp; <a href="#assignment">operator=</a>(std::auto_ptr&lt;Y&gt; &amp; r);</pre>
<p>Constructs a new <b>shared_ptr</b> as described <a href="#constructors">above</a>,
then replaces this <b>shared_ptr</b> with the new one, destroying the replaced object.
The only exception which may be thrown is <b>std::bad_alloc</b>,
which may be thrown during assignment from <b>auto_ptr</b>.
If an exception is thrown, the assignment has no effect.</p>
<h3><a name="reset">reset</a></h3>
<pre>void reset(T * p = 0);</pre>
<p>Constructs a new <b>shared_ptr</b> as described <a href="#constructors">above</a>,
then replaces this <b>shared_ptr</b> with the new one, destroying the replaced object.
The only exception which may be thrown is <b>std::bad_alloc</b>. If
an exception is thrown, <b>delete p</b> is called.</p>
<pre>template&lt;typename D&gt; void reset(T * p, D d);</pre>
<p>Constructs a new <b>shared_ptr</b> as described <a href="#constructors">above</a>,
then replaces this <b>shared_ptr</b> with the new one, destroying the replaced object.
<b>D</b>'s copy constructor must not throw.
The only exception which may be thrown is <b>std::bad_alloc</b>. If
an exception is thrown, <b>d(p)</b> is called.</p>
<h3><a name="indirection">indirection</a></h3>
<pre>T &amp; operator*() const; // never throws</pre>
<p>Returns a reference to the object pointed to by the stored pointer.
Behavior is undefined if the stored pointer is 0.</p>
<pre>T * operator-&gt;() const; // never throws</pre>
<p>Returns the stored pointer. Behavior is undefined if the stored pointer is 0.</p>
<h3><a name="get">get</a></h3>
<pre>T * get() const; // never throws</pre>
<p>Returns the stored pointer.
<b>T</b> need not be a complete type.
See the smart pointer
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
<h3><a name="unique">unique</a></h3>
<pre>bool unique() const; // never throws</pre>
<p>Returns true if no other <b>shared_ptr</b> is sharing ownership of
the stored pointer, false otherwise.
<b>T</b> need not be a complete type.
See the smart pointer
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
<h3><a name="use_count">use_count</a></h3>
<pre>long use_count() const; // never throws</pre>
<p>Returns the number of <b>shared_ptr</b> objects sharing ownership of the
stored pointer.
<b>T</b> need not be a complete type.
See the smart pointer
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
<p>Because <b>use_count</b> is not necessarily efficient to implement for
implementations of <b>shared_ptr</b> that do not use an explicit reference
count, it might be removed from some future version. Thus it should
be used for debugging purposes only, and not production code.</p>
<h3><a name="swap">swap</a></h3>
<pre>void swap(shared_ptr &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers.
<b>T</b> need not be a complete type.
See the smart pointer
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
<h2><a name="functions">Free Functions</a></h2>
<h3><a name="comparison">comparison</a></h3>
<pre>template&lt;typename T, typename U&gt;
bool operator==(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;typename T, typename U&gt;
bool operator!=(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;typename T&gt;
<h2><a name="Members">Members</a></h2>
<h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre>
<blockquote>
<p>Provides the type of the template parameter T.</p>
</blockquote>
<h3><a name="constructors">constructors</a></h3>
<pre>explicit shared_ptr(T * p = 0);</pre>
<blockquote>
<p><b>Requirements:</b> The expression <code>delete p</code> must be well-formed
and must not invoke undefined behavior.
</p>
<p><b>Effects:</b> Constructs a <b>shared_ptr</b>, storing a copy of <b>p</b>.</p>
<p><b>Postconditions:</b> <A href="#use_count">use count</A> is 1.</p>
<p><b>Throws:</b> <b>std::bad_alloc</b>.</p>
<p><b>Exception safety:</b> If an exception is thrown, <code>delete p</code> is
called.</p>
<P><STRONG>Notes:</STRONG> <B>p</B> must be a pointer to an object that was
allocated via a C++ <B>new</B> expression or be 0. The postcondition that <A href="#use_count">
use count</A> is 1 holds even if <b>p</b> is 0; invoking <STRONG>delete</STRONG>
on a pointer that has a value of 0 is harmless.</P>
</blockquote>
<pre>template&lt;typename D&gt; shared_ptr(T * p, D d);</pre>
<blockquote>
<p><b>Requirements:</b> The copy constructor and destructor of <b>D</b> must not
throw. The expression <code>d(p)</code> must be well-formed, must not invoke
undefined behavior, and must not throw exceptions.
</p>
<p><b>Effects:</b> Constructs a <b>shared_ptr</b>, storing a copy of <b>p</b> and <b>d</b>.</p>
<p><b>Postconditions:</b> <A href="#use_count">use count</A> is 1.</p>
<p><b>Throws:</b> <b>std::bad_alloc</b>.</p>
<p><b>Exception safety:</b> If an exception is thrown, <code>d(p)</code> is called.</p>
<p><b>Notes:</b> When the the time comes to delete the object pointed to by <b>p</b>,
<code>d(p)</code> is invoked.</p>
</blockquote>
<pre>shared_ptr(shared_ptr const &amp; r); // never throws
template&lt;typename Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Constructs a <b>shared_ptr</b>, as if by storing a copy of the
pointer stored in <STRONG>r</STRONG>.</p>
<p><b>Postconditions:</b> <A href="#use_count">use count</A> for all copies is
increased by one.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>shared_ptr(<A href="weak_ptr.htm" >weak_ptr</A> const &amp; r);</pre>
<blockquote>
<p><b>Effects:</b> Constructs a <b>shared_ptr</b>, as if by storing a copy of the
pointer stored in <STRONG>r</STRONG>.</p>
<p><b>Postconditions:</b> <A href="#use_count">use count</A> for all copies is
increased by one.</p>
<p><b>Throws:</b> <b>use_count_is_zero</b> when <code>r.use_count() == 0</code>.</p>
<p><b>Exception safety:</b> If an exception is thrown, the constructor has no
effect.</p>
</blockquote>
<pre>template&lt;typename Y&gt; shared_ptr(std::auto_ptr&lt;Y&gt; &amp; r);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Constructs a <B>shared_ptr</B>, as if by storing a copy of <STRONG>r.release()</STRONG>.</P>
<P><B>Postconditions:</B> <A href="#use_count">use count</A> for all copies is
increased by one.</P>
<P><B>Throws:</B> <B>std::bad_alloc</B>.</P>
<P><B>Exception safety:</B> If an exception is thrown, the constructor has no
effect.</P>
</BLOCKQUOTE>
<h3><a name="destructor">destructor</a></h3>
<pre>~shared_ptr(); // never throws</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> If <STRONG>*this</STRONG> is the sole owner (<code>use_count() == 1</code>),
destroys the object pointed to by the stored pointer.</P>
<P><B>Postconditions:</B> <A href="#use_count">use count</A> for all remaining
copies is decreased by one.</P>
<P><B>Throws:</B> nothing.</P>
<P><B>Notes:</B> <B>T</B> need not be a complete type. The guarantee that the
destructor does not throw exceptions depends on the requirement that the
deleted object's destructor does not throw exceptions. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
</BLOCKQUOTE>
<H3><a name="assignment">assignment</a></H3>
<pre>shared_ptr &amp; operator=(shared_ptr const &amp; r); // never throws
template&lt;typename Y&gt; shared_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;typename Y&gt; shared_ptr &amp; operator=(std::auto_ptr&lt;Y&gt; &amp; r);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>shared_ptr(r).swap(*this)</code>.</P>
</BLOCKQUOTE>
<h3><a name="reset">reset</a></h3>
<pre>void reset(T * p = 0);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>shared_ptr(p).swap(*this)</code>.</P>
</BLOCKQUOTE>
<pre>template&lt;typename D&gt; void reset(T * p, D d);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>shared_ptr(p, d).swap(*this)</code>.</P>
</BLOCKQUOTE>
<h3><a name="indirection">indirection</a></h3>
<pre>T &amp; operator*() const; // never throws</pre>
<blockquote>
<p><b>Requirements:</b> The stored pointer must not be 0.</p>
<p><b>Returns:</b> a reference to the object pointed to by the stored pointer.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>T * operator-&gt;() const; // never throws</pre>
<blockquote>
<p><b>Requirements:</b> The stored pointer must not be 0.</p>
<p><b>Returns:</b> the stored pointer.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3><a name="get">get</a></h3>
<pre>T * get() const; // never throws</pre>
<blockquote>
<p><b>Returns:</b> the stored pointer.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <B>T</B> need not be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
</blockquote>
<h3><a name="unique">unique</a></h3>
<pre>bool unique() const; // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>use_count() == 1</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <code>unique()</code> may be faster than <code>use_count()</code>. <B>T</B>
need not be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
</blockquote>
<h3><a name="use_count">use_count</a></h3>
<pre>long use_count() const; // never throws</pre>
<blockquote>
<p><b>Returns:</b> the number of <b>shared_ptr</b> objects sharing ownership of the
stored pointer.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only
for debugging and testing purposes, not for production code. <B>T</B> need not
be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
</blockquote>
<h3><a name="swap">swap</a></h3>
<pre>void swap(shared_ptr &amp; b); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Exchanges the contents of the two smart pointers.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <B>T</B> need not be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
</blockquote>
<h2><a name="functions">Free Functions</a></h2>
<h3><a name="comparison">comparison</a></h3>
<pre>template&lt;typename T, typename U&gt;
bool operator==(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() == b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <B>T</B> need not be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
</blockquote>
<pre>template&lt;typename T, typename U&gt;
bool operator!=(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() != b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <B>T</B> need not be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
</blockquote>
<pre>template&lt;typename T&gt;
bool operator&lt;(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;T&gt; const &amp; b); // never throws</pre>
<p>Compares the stored pointers of the two smart pointers.
<b>T</b> need not be a complete type.
See the smart pointer
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
<p>The <b>operator&lt;</b> overload is provided to define an ordering so that <b>shared_ptr</b>
objects can be used in associative containers such as <b>std::map</b>.
The implementation uses <b>std::less&lt;T *&gt;</b> to perform the
comparison. This ensures that the comparison is handled correctly, since the
standard mandates that relational operations on pointers are unspecified (5.9 [expr.rel]
paragraph 2) but <b>std::less&lt;&gt;</b> on pointers is well-defined (20.3.3 [lib.comparisons]
paragraph 8).</p>
<h3><a name="free-swap">swap</a></h3>
<pre>template&lt;typename T&gt;
<blockquote>
<p><b>Returns:</b> An implementation-defined value such that <code>operator&lt;</code>
is a strict weak ordering as described in section 25.3 <code>[lib.alg.sorting]</code>
of the C++ standard.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> Allows <STRONG>shared_ptr</STRONG> objects to be used as keys in
associative containers. <B>T</B> need not be a complete type. See the smart
pointer <A href="smart_ptr.htm#Common requirements">common requirements</A>.</P>
</blockquote>
<h3><a name="free-swap">swap</a></h3>
<pre>template&lt;typename T&gt;
void swap(shared_ptr&lt;T&gt; &amp; a, shared_ptr&lt;T&gt; &amp; b) // never throws</pre>
<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>.
Provided as an aid to generic programming.</p>
<h3><a name="shared_static_cast">shared_static_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt shared_static_cast(shared_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<p>Perform a <b>static_cast</b> on the stored pointer, returning another <b>shared_ptr</b>.
The resulting smart pointer will share its use count with the original pointer.</p>
<p>Note that the seemingly equivalent expression</p>
<blockquote><code>shared_ptr&lt;T&gt;(static_cast&lt;T*&gt;(r.get()))</code></blockquote>
<p>will eventually result in undefined behavior, attempting to delete the same object twice.</p>
<h3><a name="shared_dynamic_cast">shared_dynamic_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt shared_dynamic_cast(shared_ptr&lt;U&gt; const &amp; r);</pre>
<p>Perform a <b>dynamic_cast</b> on the stored pointer, returning another <b>shared_ptr</b>.
The resulting smart pointer will share its use count with the original pointer unless the result of the
cast is 0. The only exception which may be thrown is <b>std::bad_alloc</b>, which may be thrown during the
construction of the new <b>shared_ptr</b> if the result of the cast is 0. If an exception is thrown, the
cast has no effect.</p>
<p>Note that the seemingly equivalent expression</p>
<blockquote><code>shared_ptr&lt;T&gt;(dynamic_cast&lt;T*&gt;(r.get()))</code></blockquote>
<p>will eventually result in undefined behavior, attempting to delete the same object twice.</p>
<h3><a name="shared_polymorphic_cast">shared_polymorphic_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt shared_polymorphic_cast(shared_ptr&lt;U&gt; const &amp; r);</pre>
<p>Perform a <a href="../conversion/cast.htm#Polymorphic_cast"><b>polymorphic_cast</b><a> on the stored pointer,
returning another <b>shared_ptr</b>.
The resulting smart pointer will share its use count with the original pointer.
The only exception which may be thrown is <b>std::bad_cast</b>, if the pointer type can not be converted.
If an exception is thrown, the cast has no effect.</p>
<h3><a name="shared_polymorphic_downcast">shared_polymorphic_downcast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt shared_polymorphic_downcast(shared_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<p>Perform a <a href="../conversion/cast.htm#Polymorphic_cast"><b>polymorphic_downcast</b><a> on the stored pointer,
returning another <b>shared_ptr</b>.
The resulting smart pointer will share its use count with the original pointer.</p>
<h2><a name="example">Example</a></h2>
<p>See <a href="shared_ptr_example.cpp">shared_ptr_example.cpp</a> for a complete example program.
The program builds a <b>std::vector</b> and <b>std::set</b> of <b>shared_ptr</b> objects.</p>
<p>Note that after the containers have been populated, some of the <b>shared_ptr</b> objects
will have a use count of 1 rather than a use count of 2, since the set is a <b>std::set</b>
rather than a <b>std::multiset</b>, and thus does not contain duplicate entries.
Furthermore, the use count may be even higher
at various times while <b>push_back</b> and <b>insert</b> container operations are performed.
More complicated yet, the container operations may throw exceptions under a
variety of circumstances. Getting the memory management and exception handling in this
example right without a smart pointer would be a nightmare.</p>
<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&lt;&gt;</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.
Note that there is no need for an explicit destructor.
Unlike ~scoped_ptr, ~shared_ptr does not require that <b>T</b> be a complete type.</p>
<h2><a name="FAQ">Frequently Asked Questions</a></h2>
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> have template parameters supplying
traits or policies to allow extensive user customization?<br>
<b>A.</b> Parameterization discourages users. The <b>shared_ptr</b> template is
carefully crafted to meet common needs without extensive parameterization.
Some day 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
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>
<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
offset the added cost of an extra pointer. See <a href="smarttests.htm">timings</a>
page.</p>
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> (or any of the other Boost smart pointers)
supply an automatic conversion to <b>T*</b>?<br>
<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>
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> specify complexity requirements?<br>
<b>A.</b> Because complexity requirements 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 a release() function?<br>
<b>A.</b> <b>shared_ptr</b> cannot give away ownership unless it's unique()
because the other copy will still destroy the object.</p>
<p>Consider:</p>
<blockquote><pre>shared_ptr&lt;int&gt; a(new int);
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P>
<P><B>Throws:</B> nothing.</P>
<P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to
generic programming.</P>
</BLOCKQUOTE>
<h3><a name="shared_static_cast">shared_static_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt; shared_static_cast(shared_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<BLOCKQUOTE>
<P><STRONG>Requires:</STRONG> The expression <code>static_cast&lt;T*&gt;(r.get())</code>
must be well-formed.</P>
<P><B>Returns:</B> A <STRONG>shared_ptr&lt;T&gt;</STRONG> object that stores a copy
of <code>static_cast&lt;T*&gt;(r.get())</code> and shares ownership with <b>r</b>.</P>
<P><B>Throws:</B> nothing.</P>
<P><B>Notes:</B> the seemingly equivalent expression</P>
<p><code>shared_ptr&lt;T&gt;(static_cast&lt;T*&gt;(r.get()))</code></p>
<p>will eventually result in undefined behavior, attempting to delete the same
object twice.</p>
</BLOCKQUOTE>
<h3><a name="shared_dynamic_cast">shared_dynamic_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt; shared_dynamic_cast(shared_ptr&lt;U&gt; const &amp; r);</pre>
<BLOCKQUOTE>
<P><STRONG>Requires:</STRONG> The expression <CODE>dynamic_cast&lt;T*&gt;(r.get())</CODE>
must be well-formed and its behavior defined.</P>
<P><B>Returns:</B></P>
<UL>
<LI>
When <CODE>dynamic_cast&lt;T*&gt;(r.get())</CODE> returns a nonzero
value,&nbsp;a <STRONG>shared_ptr&lt;T&gt;</STRONG> object that stores a copy of
it and shares ownership with <STRONG>r</STRONG>;
<LI>
Otherwise, a default-constructed <STRONG>shared_ptr&lt;T&gt;</STRONG> object.</LI></UL>
<P><B>Throws:</B> <STRONG>std::bad_alloc</STRONG>.</P>
<P><B>Exception safety:</B> If an exception is thrown, the&nbsp;function has no
effect.</P>
<P><B>Notes:</B> the seemingly equivalent expression</P>
<P><CODE>shared_ptr&lt;T&gt;(dynamic_cast&lt;T*&gt;(r.get()))</CODE></P>
<P>will eventually result in undefined behavior, attempting to delete the same
object twice.</P>
</BLOCKQUOTE>
<h3><a name="shared_polymorphic_cast">shared_polymorphic_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt; shared_polymorphic_cast(shared_ptr&lt;U&gt; const &amp; r);</pre>
<BLOCKQUOTE>
<p><STRONG>Requires:</STRONG> The expression <CODE><A href="../conversion/cast.htm#Polymorphic_cast">
polymorphic_cast</A>&lt;T*&gt;(r.get())</CODE> must be well-formed and
its behavior defined.</p>
<P><B>Returns:</B> A <STRONG>shared_ptr&lt;T&gt;</STRONG> object that stores a copy
of <CODE><A href="../conversion/cast.htm#Polymorphic_cast">polymorphic_cast</A>&lt;T*&gt;(r.get())</CODE>
and shares ownership with <B>r</B>.</P>
<P><B>Throws:</B> <STRONG>std::bad_cast</STRONG>.</P>
<P><B>Exception safety:</B> If an exception is thrown, the function has no effect.</P>
</BLOCKQUOTE>
<h3><a name="shared_polymorphic_downcast">shared_polymorphic_downcast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt; shared_polymorphic_downcast(shared_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<BLOCKQUOTE>
<p><STRONG>Requires:</STRONG> The expression <CODE><A href="../conversion/cast.htm#Polymorphic_cast">
polymorphic_downcast</A>&lt;T*&gt;(r.get())</CODE> must be well-formed
and its behavior defined.</p>
<P><B>Returns:</B> A <STRONG>shared_ptr&lt;T&gt;</STRONG> object that stores a copy
of <CODE><A href="../conversion/cast.htm#Polymorphic_cast">polymorphic_downcast</A>&lt;T*&gt;(r.get())</CODE>
and shares ownership with <B>r</B>.</P>
<P><B>Throws:</B> nothing.</P>
</BLOCKQUOTE>
<h2><a name="example">Example</a></h2>
<p>See <A href="shared_ptr_example.cpp">shared_ptr_example.cpp</A> for a complete
example program. The program builds a <b>std::vector</b> and <b>std::set</b> of <b>shared_ptr</b>
objects.</p>
<p>Note that after the containers have been populated, some of the <b>shared_ptr</b>
objects will have a use count of 1 rather than a use count of 2, since the set
is a <b>std::set</b> rather than a <b>std::multiset</b>, and thus does not
contain duplicate entries. Furthermore, the use count may be even higher at
various times while <b>push_back</b> and <b>insert</b> container operations are
performed. More complicated yet, the container operations may throw exceptions
under a variety of circumstances. Getting the memory management and exception
handling in this example right without a smart pointer would be a nightmare.</p>
<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&lt;&gt;</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. Note that there is no need for an explicit destructor.
Unlike ~scoped_ptr, ~shared_ptr does not require that <b>T</b> be a complete
type.</p>
<h2><a name="FAQ">Frequently Asked Questions</a></h2>
<P><B>Q.</B> There are several variations of shared pointers, with different
tradeoffs; why does the smart pointer library supply only a single
implementation? It would be useful to be able to experiment with each type so
as to find the most suitable for the job at hand?<BR>
<b>A.</b> An important goal of <STRONG>shared_ptr</STRONG> is to provide a
standard shared-ownership pointer. Having a single pointer type is important
for stable library interfaces, since different shared pointers typically cannot
interoperate, i.e. a reference counted pointer (used by library A) cannot share
ownership with a linked pointer (used by library B.)</P>
<P><B>Q.</B> Why doesn't <B>shared_ptr</B> have template parameters supplying
traits or policies to allow extensive user customization?<BR>
<B>A.</B> Parameterization discourages users. The <B>shared_ptr</B> template is
carefully crafted to meet common needs without extensive parameterization. Some
day 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 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>
<P><B>Q.</B> I am not convinced. Default parameters can be use where appropriate to
hide the complexity. Again, why not policies?<BR>
<B>A.</B> Template parameters affect the type. See the answer to the first
question above.</P>
<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
offset the added cost of an extra pointer. See <A href="smarttests.htm">timings</A>
page. In addition, it is expensive to make a linked list implementation thread
safe.</p>
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> (or any of the other Boost smart
pointers) supply an automatic conversion to <b>T*</b>?<br>
<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>
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> specify complexity requirements?<br>
<b>A.</b> Because complexity requirements 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 a release() function?<br>
<b>A.</b> <b>shared_ptr</b> cannot give away ownership unless it's unique()
because the other copy will still destroy the object.</p>
<p>Consider:</p>
<blockquote><pre>shared_ptr&lt;int&gt; a(new int);
shared_ptr&lt;int&gt; b(a); // a.use_count() == b.use_count() == 2
int * p = a.release();
// Who owns p now? b will still call delete on it in its destructor.</pre></blockquote>
<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
implementation or a linked list implementation, or some other specific implementation.
This is not the intent.</p>
<hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->8 February 2002<!--webbot bot="Timestamp" i-checksum="38439" endspan --></p>
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies.
This document is provided &quot;as is&quot; without express or implied warranty,
and with no claim as to its suitability for any purpose.</p>
</body>
// Who owns p now? b will still call delete on it in its destructor.</pre>
</blockquote>
<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
implementation or a linked list implementation, or some other specific
implementation. This is not the intent.</p>
<hr>
<p>Revised&nbsp; <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->
14 February 2002<!--webbot bot="Timestamp" i-checksum="38439" endspan --></p>
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002 Peter Dimov. 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>
</html>