Merged [51699] and [51700] from trunk to release.

Closes #1897


[SVN r51703]
This commit is contained in:
Frank Mori Hess
2009-03-11 15:08:14 +00:00
parent 31e06b4a1d
commit 1742c37942
3 changed files with 361 additions and 226 deletions

119
make_shared.html Normal file
View File

@@ -0,0 +1,119 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>make_shared and allocate_shared</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
border="0"></A>make_shared and allocate_shared function templates</h1>
<p><A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
<A href="#functions">Free Functions</A><br>
<A href="#example">Example</A><br>
<h2><a name="Introduction">Introduction</a></h2>
<p>Consistent use of <a href="shared_ptr.htm"><code>shared_ptr</code></a>
can eliminate the need to use an explicit <code>delete</code>,
but alone it provides no support in avoiding explicit <code>new</code>.
There have been repeated requests from users for a factory function that creates
an object of a given type and returns a <code>shared_ptr</code> to it.
Besides convenience and style, such a function is also exception safe and
considerably faster because it can use a single allocation for both the object
and its corresponding control block, eliminating a significant portion of
<code>shared_ptr</code>'s construction overhead.
This eliminates one of the major efficiency complaints about <code>shared_ptr</code>.
</p>
<p>The header file &lt;boost/make_shared.hpp&gt; provides a family of overloaded function templates,
<code>make_shared</code> and <code>allocate_shared</code>, to address this need.
<code>make_shared</code> uses the global operator <code>new</code> to allocate memory,
whereas <code>allocate_shared</code> uses an user-supplied allocator, allowing finer control.</p>
<p>
The rationale for choosing the name <code>make_shared</code> is that the expression
<code>make_shared&lt;Widget&gt;()</code> can be read aloud and conveys the intended meaning.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;typename T&gt; class shared_ptr;
template&lt;typename T&gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>();
template&lt;typename T, typename A&gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; );
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS ) // C++0x prototypes
template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Args &amp;&amp; ... args );
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; a, Args &amp;&amp; ... args );
#else // no C++0X support
template&lt;typename T, typename Arg1 &gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Arg1 const &amp; arg1 );
template&lt;typename T, typename Arg1, typename Arg2 &gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Arg1 const &amp; arg1, Arg2 const &amp; arg2 );
// ...
template&lt;typename T, typename Arg1, typename Arg2, ..., typename ArgN &gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Arg1 const &amp; arg1, Arg2 const &amp; arg2, ..., ArgN const &amp; argN );
template&lt;typename T, typename A, typename Arg1 &gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; a, Arg1 const &amp; arg1 );
template&lt;typename T, typename A, typename Arg1, typename Arg2 &gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( Arg1 const &amp; arg1, Arg2 const &amp; arg2 );
// ...
template&lt;typename T, typename A, typename Arg1, typename Arg2, ..., typename ArgN &gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; a, Arg1 const &amp; arg1, Arg2 const &amp; arg2, ..., ArgN const &amp; argN );
#endif
}</pre>
<h2><a name="functions">Free Functions</a></h2>
<pre>template&lt;class T, class... Args&gt;
shared_ptr&lt;T&gt; make_shared( Args &amp;&amp; ... args );
template&lt;class T, class A, class... Args&gt;
shared_ptr&lt;T&gt; allocate_shared( A const &amp; a, Args &amp;&amp; ... args );</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>new( pv ) T( std::forward&lt;Args&gt;(args)... )</code>,
where <code>pv</code> is a <code>void*</code> pointing to storage suitable
to hold an object of type <code>T</code>,
shall be well-formed. <code>A</code> shall be an <em>Allocator</em>,
as described in section 20.1.5 (<stong>Allocator requirements</strong>) of the C++ Standard.
The copy constructor and destructor of <code>A</code> shall not throw.</p>
<p><b>Effects:</b> Allocates memory suitable for an object of type <code>T</code>
and constructs an object in it via the placement new expression <code>new( pv ) T()</code>
or <code>new( pv ) T( std::forward&lt;Args&gt;(args)... )</code>.
<code>allocate_shared</code> uses a copy of <code>a</code> to allocate memory.
If an exception is thrown, has no effect.</p>
<p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and owns the address
of the newly constructed object of type <code>T</code>.</p>
<p><b>Postconditions:</b> <code>get() != 0 &amp;&amp; use_count() == 1</code>.</p>
<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from <code>A::allocate</code>
or the constructor of <code>T</code>.</p>
<p><b>Notes:</b> This implementation allocates the memory required for the
returned <code>shared_ptr</code> and an object of type <code>T</code> in a single
allocation. This provides efficiency equivalent to an intrusive smart pointer.</p>
<p>The prototypes shown above are used if your compiler supports rvalue references
and variadic templates. They perfectly forward the <code>args</code> parameters to
the constructors of <code>T</code>.</p>
<p>Otherwise, the implementation will fall back on
forwarding the arguments to the constructors of <code>T</code> as const references.
If you need to pass a non-const reference to a constructor of <code>T</code>,
you may do so by wrapping the parameter in a call to <code>boost::ref</code>.
In addition, you will be
limited to a maximum of 9 arguments (not counting the allocator argument of
allocate_shared).</p>
</blockquote>
<h2><a name="example">Example</a></h2>
<pre>boost::shared_ptr&lt;std::string&gt; x = boost::make_shared&lt;std::string&gt;("hello, world!");
std::cout << *x;</pre>
<hr>
<p>
$Date: 2008-05-19 15:42:39 -0400 (Mon, 19 May 2008) $</p>
<p><small>Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess.
Distributed under the Boost Software License,
Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@@ -19,54 +19,54 @@
<A href="smarttests.htm">Smart Pointer Timings</A><br> <A href="smarttests.htm">Smart Pointer Timings</A><br>
<A href="sp_techniques.html">Programming Techniques</A></p> <A href="sp_techniques.html">Programming Techniques</A></p>
<h2><a name="Introduction">Introduction</a></h2> <h2><a name="Introduction">Introduction</a></h2>
<p>The <b>shared_ptr</b> class template stores a pointer to a dynamically allocated <p>The <b>shared_ptr</b> class template stores a pointer to a dynamically allocated
object, typically with a C++ <EM>new-expression</EM>. The object pointed to is object, typically with a C++ <EM>new-expression</EM>. The object pointed to is
guaranteed to be deleted when the last <b>shared_ptr</b> pointing to it 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> 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> <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 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> library containers. Comparison operators are supplied so that <b>shared_ptr</b>
works with the standard library's associative containers.</p> works with the standard library's associative containers.</p>
<p>Normally, a <b>shared_ptr</b> cannot correctly hold a pointer to a dynamically <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 allocated array. See <A href="shared_array.htm"><b>shared_array</b></A> for
that usage.</p> that usage.</p>
<p>Because the implementation uses reference counting, cycles of <b>shared_ptr</b> instances <p>Because the implementation uses reference counting, cycles of <b>shared_ptr</b> instances
will not be reclaimed. For example, if <b>main()</b> holds a <b>shared_ptr</b> to will not be reclaimed. 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>, 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 <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. Use <A href="weak_ptr.htm">weak_ptr</A> leave <b>A</b> dangling with a use count of 1. Use <A href="weak_ptr.htm">weak_ptr</A>
to "break cycles."</p> to "break cycles."</p>
<p>The class template is parameterized on <b>T</b>, the type of the object pointed <p>The class template is parameterized on <b>T</b>, the type of the object pointed
to. <STRONG>shared_ptr</STRONG> and most of its member functions place no to. <STRONG>shared_ptr</STRONG> and most of its member functions place no
requirements on <STRONG>T</STRONG>; it is allowed to be an incomplete type, or <STRONG> requirements on <STRONG>T</STRONG>; it is allowed to be an incomplete type, or <STRONG>
void</STRONG>. Member functions that do place additional requirements (<A href="#constructors">constructors</A>, void</STRONG>. Member functions that do place additional requirements (<A href="#constructors">constructors</A>,
<A href="#reset">reset</A>) are explicitly documented below.</p> <A href="#reset">reset</A>) are explicitly documented below.</p>
<P><STRONG>shared_ptr&lt;T&gt;</STRONG> can be implicitly converted to <STRONG>shared_ptr&lt;U&gt;</STRONG> <P><STRONG>shared_ptr&lt;T&gt;</STRONG> can be implicitly converted to <STRONG>shared_ptr&lt;U&gt;</STRONG>
whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>. whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>.
In particular, <STRONG>shared_ptr&lt;T&gt;</STRONG> is implicitly convertible In particular, <STRONG>shared_ptr&lt;T&gt;</STRONG> is implicitly convertible
to <STRONG>shared_ptr&lt;T const&gt;</STRONG>, to <STRONG>shared_ptr&lt;U&gt;</STRONG> to <STRONG>shared_ptr&lt;T const&gt;</STRONG>, to <STRONG>shared_ptr&lt;U&gt;</STRONG>
where <STRONG>U</STRONG> is an accessible base of <STRONG>T</STRONG>, and to <STRONG> where <STRONG>U</STRONG> is an accessible base of <STRONG>T</STRONG>, and to <STRONG>
shared_ptr&lt;void&gt;</STRONG>.</P> shared_ptr&lt;void&gt;</STRONG>.</P>
<P><STRONG>shared_ptr</STRONG> is now part of <STRONG>TR1</STRONG>, the first C++ <P><STRONG>shared_ptr</STRONG> is now part of <STRONG>TR1</STRONG>, the first C++
Library Technical Report. The latest draft of <STRONG>TR1</STRONG> is available Library Technical Report. The latest draft of <STRONG>TR1</STRONG> is available
at the following location:</P> at the following location:</P>
<P><A href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf</A> <P><A href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf</A>
(1.36Mb PDF)</P> (1.36Mb PDF)</P>
<P>This implementation conforms to the TR1 specification, with the only exception <P>This implementation conforms to the TR1 specification, with the only exception
that it resides in namespace <code>boost</code> instead of <code>std::tr1</code>.</P> that it resides in namespace <code>boost</code> instead of <code>std::tr1</code>.</P>
<h2><a name="BestPractices">Best Practices</a></h2> <h2><a name="BestPractices">Best Practices</a></h2>
<P>A simple guideline that nearly eliminates the possibility of memory leaks is: <P>A simple guideline that nearly eliminates the possibility of memory leaks is:
always use a named smart pointer variable to hold the result of <STRONG>new. </STRONG> always use a named smart pointer variable to hold the result of <STRONG>new. </STRONG>
Every occurence of the <STRONG>new</STRONG> keyword in the code should have the Every occurence of the <STRONG>new</STRONG> keyword in the code should have the
form:</P> form:</P>
<PRE>shared_ptr&lt;T&gt; p(new Y);</PRE> <PRE>shared_ptr&lt;T&gt; p(new Y);</PRE>
<P>It is, of course, acceptable to use another smart pointer in place of <STRONG>shared_ptr</STRONG> <P>It is, of course, acceptable to use another smart pointer in place of <STRONG>shared_ptr</STRONG>
above; having <STRONG>T</STRONG> and <STRONG>Y</STRONG> be the same type, or above; having <STRONG>T</STRONG> and <STRONG>Y</STRONG> be the same type, or
passing arguments to <STRONG>Y</STRONG>'s constructor is also OK.</P> passing arguments to <STRONG>Y</STRONG>'s constructor is also OK.</P>
<P>If you observe this guideline, it naturally follows that you will have no <P>If you observe this guideline, it naturally follows that you will have no
explicit <STRONG>delete</STRONG>s; <STRONG>try/catch</STRONG> constructs will explicit <STRONG>delete</STRONG>s; <STRONG>try/catch</STRONG> constructs will
be rare.</P> be rare.</P>
<P>Avoid using unnamed <STRONG>shared_ptr</STRONG> temporaries to save typing; to <P>Avoid using unnamed <STRONG>shared_ptr</STRONG> temporaries to save typing; to
see why this is dangerous, consider this example:</P> see why this is dangerous, consider this example:</P>
<PRE>void f(shared_ptr&lt;int&gt;, int); <PRE>void f(shared_ptr&lt;int&gt;, int);
int g(); int g();
@@ -83,13 +83,18 @@ void bad()
} }
</PRE> </PRE>
<P>The function <STRONG>ok</STRONG> follows the guideline to the letter, whereas <STRONG> <P>The function <STRONG>ok</STRONG> follows the guideline to the letter, whereas <STRONG>
bad</STRONG> constructs the temporary <STRONG>shared_ptr</STRONG> in place, bad</STRONG> constructs the temporary <STRONG>shared_ptr</STRONG> in place,
admitting the possibility of a memory leak. Since function arguments are admitting the possibility of a memory leak. Since function arguments are
evaluated in unspecified order, it is possible for <STRONG>new int(2)</STRONG> to evaluated in unspecified order, it is possible for <STRONG>new int(2)</STRONG> to
be evaluated first, <STRONG>g()</STRONG> second, and we may never get to the <STRONG> be evaluated first, <STRONG>g()</STRONG> second, and we may never get to the <STRONG>
shared_ptr </STRONG>constructor if <STRONG>g</STRONG> throws an exception. shared_ptr </STRONG>constructor if <STRONG>g</STRONG> throws an exception.
See <A href="http://www.gotw.ca/gotw/056.htm">Herb Sutter's treatment</A> (also <A href="http://www.cuj.com/reference/articles/2002/0212/0212_sutter.htm"> See <A href="http://www.gotw.ca/gotw/056.htm">Herb Sutter's treatment</A> (also <A href="http://www.cuj.com/reference/articles/2002/0212/0212_sutter.htm">
here</A>) of the issue for more information.</P> here</A>) of the issue for more information.</P>
<P>The exception safety problem described above may also be eliminated by using
the <a href="make_shared.html"><code>make_shared</code></a>
or <a href="make_shared.html"><code>allocate_shared</code></a>
factory functions defined in boost/make_shared.hpp. These factory functions also provide
an efficiency benefit by consolidating allocations.<P>
<h2><a name="Synopsis">Synopsis</a></h2> <h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost { <pre>namespace boost {
@@ -115,7 +120,7 @@ void bad()
template&lt;class Y&gt; explicit <A href="#constructors" >shared_ptr</A>(<A href="weak_ptr.htm" >weak_ptr</A>&lt;Y&gt; const &amp; r); template&lt;class Y&gt; explicit <A href="#constructors" >shared_ptr</A>(<A href="weak_ptr.htm" >weak_ptr</A>&lt;Y&gt; const &amp; r);
template&lt;class Y&gt; explicit <A href="#constructors" >shared_ptr</A>(std::auto_ptr&lt;Y&gt; &amp; r); template&lt;class Y&gt; explicit <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 shared_ptr &amp; <A href="#assignment" >operator=</A>(shared_ptr const &amp; r); // never throws
template&lt;class Y&gt; shared_ptr &amp; <A href="#assignment" >operator=</A>(shared_ptr&lt;Y&gt; const &amp; r); // never throws template&lt;class Y&gt; shared_ptr &amp; <A href="#assignment" >operator=</A>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;class Y&gt; shared_ptr &amp; <A href="#assignment" >operator=</A>(std::auto_ptr&lt;Y&gt; &amp; r); template&lt;class Y&gt; shared_ptr &amp; <A href="#assignment" >operator=</A>(std::auto_ptr&lt;Y&gt; &amp; r);
@@ -178,32 +183,32 @@ void bad()
<p><b>Postconditions:</b> <code>use_count() == 0 &amp;&amp; get() == 0</code>.</p> <p><b>Postconditions:</b> <code>use_count() == 0 &amp;&amp; get() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p> <p><b>Throws:</b> nothing.</p>
</blockquote> </blockquote>
<P><EM>[The nothrow guarantee is important, since <STRONG>reset()</STRONG> is specified <P><EM>[The nothrow guarantee is important, since <STRONG>reset()</STRONG> is specified
in terms of the default constructor; this implies that the constructor must not in terms of the default constructor; this implies that the constructor must not
allocate memory.]</EM></P> allocate memory.]</EM></P>
<pre>template&lt;class Y&gt; explicit shared_ptr(Y * p);</pre> <pre>template&lt;class Y&gt; explicit shared_ptr(Y * p);</pre>
<blockquote> <blockquote>
<p><b>Requirements:</b> <b>p</b> must be convertible to <b>T *</b>. <STRONG>Y</STRONG> <p><b>Requirements:</b> <b>p</b> must be convertible to <b>T *</b>. <STRONG>Y</STRONG>
must be a complete type. The expression <code>delete p</code> must be must be a complete type. The expression <code>delete p</code> must be
well-formed, must not invoke undefined behavior, and must not throw exceptions. well-formed, must not invoke undefined behavior, and must not throw exceptions.
</p> </p>
<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>owns</EM> the pointer <b>p</b>.</p> <p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>owns</EM> the pointer <b>p</b>.</p>
<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.</p> <p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.</p>
<p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined <p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p> exception when a resource other than memory could not be obtained.</p>
<p><b>Exception safety:</b> If an exception is thrown, <code>delete p</code> is <p><b>Exception safety:</b> If an exception is thrown, <code>delete p</code> is
called.</p> called.</p>
<P><STRONG>Notes:</STRONG> <B>p</B> must be a pointer to an object that was <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"> 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> 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> on a pointer that has a value of 0 is harmless.</P>
</blockquote> </blockquote>
<P><EM>[This constructor has been changed to a template in order to remember the actual <P><EM>[This constructor has been changed to a template in order to remember the actual
pointer type passed. The destructor will call <STRONG>delete</STRONG> with the pointer type passed. The destructor will call <STRONG>delete</STRONG> with the
same pointer, complete with its original type, even when <STRONG>T</STRONG> does same pointer, complete with its original type, even when <STRONG>T</STRONG> does
not have a virtual destructor, or is <STRONG>void</STRONG>.</EM></P> not have a virtual destructor, or is <STRONG>void</STRONG>.</EM></P>
<P><EM>The optional intrusive counting support has been dropped as it exposes too much <P><EM>The optional intrusive counting support has been dropped as it exposes too much
implementation details and doesn't interact well with <STRONG>weak_ptr</STRONG>. implementation details and doesn't interact well with <STRONG>weak_ptr</STRONG>.
The current implementation uses a different mechanism, <A href="enable_shared_from_this.html"> The current implementation uses a different mechanism, <A href="enable_shared_from_this.html">
enable_shared_from_this</A>, to solve the "<STRONG>shared_ptr</STRONG> from <STRONG> enable_shared_from_this</A>, to solve the "<STRONG>shared_ptr</STRONG> from <STRONG>
this</STRONG>" problem.</EM><EM>]</EM></P> this</STRONG>" problem.</EM><EM>]</EM></P>
@@ -212,46 +217,46 @@ void bad()
template&lt;class Y, class D, class A&gt; shared_ptr(Y * p, D d, A a);</pre> template&lt;class Y, class D, class A&gt; shared_ptr(Y * p, D d, A a);</pre>
<blockquote> <blockquote>
<p><b>Requirements:</b> <B>p</B> must be convertible to <B>T *</B>. <STRONG>D</STRONG> <p><b>Requirements:</b> <B>p</B> must be convertible to <B>T *</B>. <STRONG>D</STRONG>
must be <STRONG>CopyConstructible</STRONG>. The copy constructor and destructor must be <STRONG>CopyConstructible</STRONG>. The copy constructor and destructor
of <b>D</b> must not throw. The expression <code>d(p)</code> must be 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. <STRONG> well-formed, must not invoke undefined behavior, and must not throw exceptions. <STRONG>
A</STRONG> must be an <EM>Allocator</EM>, as described in section 20.1.5 (<STRONG>Allocator A</STRONG> must be an <EM>Allocator</EM>, as described in section 20.1.5 (<STRONG>Allocator
requirements</STRONG>) of the C++ Standard. requirements</STRONG>) of the C++ Standard.
</p> </p>
<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>owns</EM> the pointer <STRONG> <p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>owns</EM> the pointer <STRONG>
p</STRONG> and the deleter <b>d</b>. The second constructor allocates p</STRONG> and the deleter <b>d</b>. The second constructor allocates
memory using a copy of <STRONG>a</STRONG>.</p> memory using a copy of <STRONG>a</STRONG>.</p>
<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.</p> <p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.</p>
<p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined <p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p> exception when a resource other than memory could not be obtained.</p>
<p><b>Exception safety:</b> If an exception is thrown, <code>d(p)</code> is called.</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>, <p><b>Notes:</b> When the the time comes to delete the object pointed to by <b>p</b>,
the stored copy of <STRONG>d</STRONG> is invoked with the stored copy of <STRONG>p</STRONG> the stored copy of <STRONG>d</STRONG> is invoked with the stored copy of <STRONG>p</STRONG>
as an argument.</p> as an argument.</p>
</blockquote> </blockquote>
<P><EM>[Custom deallocators allow a factory function returning a <STRONG>shared_ptr</STRONG> <P><EM>[Custom deallocators allow a factory function returning a <STRONG>shared_ptr</STRONG>
to insulate the user from its memory allocation strategy. Since the deallocator to insulate the user from its memory allocation strategy. Since the deallocator
is not part of the type, changing the allocation strategy does not break source is not part of the type, changing the allocation strategy does not break source
or binary compatibility, and does not require a client recompilation. For or binary compatibility, and does not require a client recompilation. For
example, a "no-op" deallocator is useful when returning a <STRONG>shared_ptr</STRONG> example, a "no-op" deallocator is useful when returning a <STRONG>shared_ptr</STRONG>
to a statically allocated object, and other variations allow a <STRONG>shared_ptr</STRONG> to a statically allocated object, and other variations allow a <STRONG>shared_ptr</STRONG>
to be used as a wrapper for another smart pointer, easing interoperability.</EM></P> to be used as a wrapper for another smart pointer, easing interoperability.</EM></P>
<P><EM>The support for custom deallocators does not impose significant overhead. Other <STRONG> <P><EM>The support for custom deallocators does not impose significant overhead. Other <STRONG>
shared_ptr</STRONG> features still require a deallocator to be kept.</EM></P> shared_ptr</STRONG> features still require a deallocator to be kept.</EM></P>
<P><EM>The requirement that the copy constructor of <b>D</b> does not throw comes from <P><EM>The requirement that the copy constructor of <b>D</b> does not throw comes from
the pass by value. If the copy constructor throws, the pointer is leaked. the pass by value. If the copy constructor throws, the pointer is leaked.
Removing the requirement requires a pass by (const) reference.</EM></P> Removing the requirement requires a pass by (const) reference.</EM></P>
<P><EM>The main problem with pass by reference lies in its interaction with rvalues. A <P><EM>The main problem with pass by reference lies in its interaction with rvalues. A
const reference may still cause a copy, and will require a const operator(). A const reference may still cause a copy, and will require a const operator(). A
non-const reference won't bind to an rvalue at all. A good solution to this non-const reference won't bind to an rvalue at all. A good solution to this
problem is the rvalue reference proposed in <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm"> problem is the rvalue reference proposed in <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm">
N1377</A>/<A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">N1385</A>.]</EM></P> N1377</A>/<A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">N1385</A>.]</EM></P>
<pre>shared_ptr(shared_ptr const &amp; r); // never throws <pre>shared_ptr(shared_ptr const &amp; r); // never throws
template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never throws</pre> template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never throws</pre>
<blockquote> <blockquote>
<p><b>Effects:</b> If <b>r</b> is <EM>empty</EM>, constructs an <EM>empty</EM> <b>shared_ptr</b>; <p><b>Effects:</b> If <b>r</b> is <EM>empty</EM>, constructs an <EM>empty</EM> <b>shared_ptr</b>;
otherwise, constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with <b>r</b>.</p> otherwise, constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with <b>r</b>.</p>
<p><b>Postconditions:</b> <code>get() == r.get() &amp;&amp; use_count() == <p><b>Postconditions:</b> <code>get() == r.get() &amp;&amp; use_count() ==
r.use_count()</code>.</p> r.use_count()</code>.</p>
<p><b>Throws:</b> nothing.</p> <p><b>Throws:</b> nothing.</p>
</blockquote> </blockquote>
@@ -268,21 +273,21 @@ template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never
<b>r</b> and stores a copy of the pointer stored in <STRONG>r</STRONG>.</p> <b>r</b> and stores a copy of the pointer stored in <STRONG>r</STRONG>.</p>
<p><b>Postconditions:</b> <code>use_count() == r.use_count()</code>.</p> <p><b>Postconditions:</b> <code>use_count() == r.use_count()</code>.</p>
<p><b>Throws:</b> <b>bad_weak_ptr</b> when <code>r.use_count() == 0</code>.</p> <p><b>Throws:</b> <b>bad_weak_ptr</b> when <code>r.use_count() == 0</code>.</p>
<p><b>Exception safety:</b> If an exception is thrown, the constructor has no <p><b>Exception safety:</b> If an exception is thrown, the constructor has no
effect.</p> effect.</p>
</blockquote> </blockquote>
<pre>template&lt;class Y&gt; shared_ptr(std::auto_ptr&lt;Y&gt; &amp; r);</pre> <pre>template&lt;class Y&gt; shared_ptr(std::auto_ptr&lt;Y&gt; &amp; r);</pre>
<BLOCKQUOTE> <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>Effects:</B> Constructs a <B>shared_ptr</B>, as if by storing a copy of <STRONG>r.release()</STRONG>.</P>
<p><b>Postconditions:</b> <code>use_count() == 1</code>.</p> <p><b>Postconditions:</b> <code>use_count() == 1</code>.</p>
<p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined <p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p> exception when a resource other than memory could not be obtained.</p>
<P><B>Exception safety:</B> If an exception is thrown, the constructor has no <P><B>Exception safety:</B> If an exception is thrown, the constructor has no
effect.</P> effect.</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><EM>[This constructor takes a the source <STRONG>auto_ptr</STRONG> by reference and <P><EM>[This constructor takes a the source <STRONG>auto_ptr</STRONG> by reference and
not by value, and cannot accept <STRONG>auto_ptr</STRONG> temporaries. This is not by value, and cannot accept <STRONG>auto_ptr</STRONG> temporaries. This is
by design, as the constructor offers the strong guarantee; an rvalue reference by design, as the constructor offers the strong guarantee; an rvalue reference
would solve this problem, too.]</EM></P> would solve this problem, too.]</EM></P>
<h3><a name="destructor">destructor</a></h3> <h3><a name="destructor">destructor</a></h3>
<pre>~shared_ptr(); // never throws</pre> <pre>~shared_ptr(); // never throws</pre>
@@ -290,15 +295,15 @@ template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never
<P><B>Effects:</B></P> <P><B>Effects:</B></P>
<UL> <UL>
<LI> <LI>
If <STRONG>*this</STRONG> is <EM>empty</EM>, or <EM>shares ownership</EM> with If <STRONG>*this</STRONG> is <EM>empty</EM>, or <EM>shares ownership</EM> with
another <STRONG>shared_ptr</STRONG> instance (<code>use_count() &gt; 1</code>), another <STRONG>shared_ptr</STRONG> instance (<code>use_count() &gt; 1</code>),
there are no side effects. there are no side effects.
<LI> <LI>
Otherwise, if <STRONG>*this</STRONG> <EM>owns</EM> a pointer <STRONG>p</STRONG> Otherwise, if <STRONG>*this</STRONG> <EM>owns</EM> a pointer <STRONG>p</STRONG>
and a deleter <STRONG>d</STRONG>, <code>d(p)</code> and a deleter <STRONG>d</STRONG>, <code>d(p)</code>
is called. is called.
<LI> <LI>
Otherwise, <STRONG>*this</STRONG> <EM>owns</EM> a pointer <STRONG>p</STRONG>, Otherwise, <STRONG>*this</STRONG> <EM>owns</EM> a pointer <STRONG>p</STRONG>,
and <code>delete p</code> is called.</LI></UL> and <code>delete p</code> is called.</LI></UL>
<P><B>Throws:</B> nothing.</P> <P><B>Throws:</B> nothing.</P>
</BLOCKQUOTE> </BLOCKQUOTE>
@@ -309,9 +314,9 @@ template&lt;class Y&gt; shared_ptr &amp; operator=(std::auto_ptr&lt;Y&gt; &amp;
<BLOCKQUOTE> <BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>shared_ptr(r).swap(*this)</code>.</P> <P><B>Effects:</B> Equivalent to <code>shared_ptr(r).swap(*this)</code>.</P>
<P><B>Returns:</B> <code>*this</code>.</P> <P><B>Returns:</B> <code>*this</code>.</P>
<P><B>Notes:</B> The use count updates caused by the temporary object construction <P><B>Notes:</B> The use count updates caused by the temporary object construction
and destruction are not considered observable side effects, and the and destruction are not considered observable side effects, and the
implementation is free to meet the effects (and the implied guarantees) via implementation is free to meet the effects (and the implied guarantees) via
different means, without creating a temporary. In particular, in the example:</P> different means, without creating a temporary. In particular, in the example:</P>
<pre>shared_ptr&lt;int&gt; p(new int); <pre>shared_ptr&lt;int&gt; p(new int);
shared_ptr&lt;void&gt; q(p); shared_ptr&lt;void&gt; q(p);
@@ -365,32 +370,32 @@ q = p;
<blockquote> <blockquote>
<p><b>Returns:</b> <code>use_count() == 1</code>.</p> <p><b>Returns:</b> <code>use_count() == 1</code>.</p>
<p><b>Throws:</b> nothing.</p> <p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <code>unique()</code> may be faster than <code>use_count()</code>. <P><B>Notes:</B> <code>unique()</code> may be faster than <code>use_count()</code>.
If you are using <code>unique()</code> to implement copy on write, do not rely If you are using <code>unique()</code> to implement copy on write, do not rely
on a specific value when the stored pointer is zero.</P> on a specific value when the stored pointer is zero.</P>
</blockquote> </blockquote>
<h3><a name="use_count">use_count</a></h3> <h3><a name="use_count">use_count</a></h3>
<pre>long use_count() const; // never throws</pre> <pre>long use_count() const; // never throws</pre>
<blockquote> <blockquote>
<p><b>Returns:</b> the number of <b>shared_ptr</b> objects, <STRONG>*this</STRONG> included, <p><b>Returns:</b> the number of <b>shared_ptr</b> objects, <STRONG>*this</STRONG> included,
that <i>share ownership</i> with <b>*this</b>, or 0 when <STRONG>*this</STRONG> that <i>share ownership</i> with <b>*this</b>, or 0 when <STRONG>*this</STRONG>
is <EM>empty</EM>.</p> is <EM>empty</EM>.</p>
<p><b>Throws:</b> nothing.</p> <p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only <P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only
for debugging and testing purposes, not for production code.</P> for debugging and testing purposes, not for production code.</P>
</blockquote> </blockquote>
<h3><a name="conversions">conversions</a></h3> <h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre> <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<blockquote> <blockquote>
<p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is <p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is
equivalent to <code>get() != 0</code>.</p> equivalent to <code>get() != 0</code>.</p>
<p><b>Throws:</b> nothing.</p> <p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> This conversion operator allows <b>shared_ptr</b> objects to be <P><B>Notes:</B> This conversion operator allows <b>shared_ptr</b> objects to be
used in boolean contexts, like <code>if (p &amp;&amp; p-&gt;valid()) {}</code>. used in boolean contexts, like <code>if (p &amp;&amp; p-&gt;valid()) {}</code>.
The actual target type is typically a pointer to a member function, avoiding The actual target type is typically a pointer to a member function, avoiding
many of the implicit conversion pitfalls.</P> many of the implicit conversion pitfalls.</P>
</blockquote> </blockquote>
<P><EM>[The conversion to bool is not merely syntactic sugar. It allows <STRONG>shared_ptr</STRONG>s <P><EM>[The conversion to bool is not merely syntactic sugar. It allows <STRONG>shared_ptr</STRONG>s
to be declared in conditions when using <A href="#dynamic_pointer_cast">dynamic_pointer_cast</A> to be declared in conditions when using <A href="#dynamic_pointer_cast">dynamic_pointer_cast</A>
or <A href="weak_ptr.htm#lock">weak_ptr::lock</A>.]</EM></P> or <A href="weak_ptr.htm#lock">weak_ptr::lock</A>.]</EM></P>
<h3><a name="swap">swap</a></h3> <h3><a name="swap">swap</a></h3>
@@ -422,19 +427,19 @@ q = p;
<b>operator&lt;</b> is a strict weak ordering as described in section 25.3 <code>[lib.alg.sorting]</code> <b>operator&lt;</b> is a strict weak ordering as described in section 25.3 <code>[lib.alg.sorting]</code>
of the C++ standard; of the C++ standard;
<LI> <LI>
under the equivalence relation defined by <STRONG>operator&lt;</STRONG>, <code>!(a under the equivalence relation defined by <STRONG>operator&lt;</STRONG>, <code>!(a
&lt; b) &amp;&amp; !(b &lt; a)</code>, two <STRONG>shared_ptr</STRONG> instances &lt; b) &amp;&amp; !(b &lt; a)</code>, two <STRONG>shared_ptr</STRONG> instances
are equivalent if and only if they <EM>share ownership</EM> or are both <EM>empty</EM>.</LI></UL> are equivalent if and only if they <EM>share ownership</EM> or are both <EM>empty</EM>.</LI></UL>
<p><b>Throws:</b> nothing.</p> <p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> Allows <STRONG>shared_ptr</STRONG> objects to be used as keys in <P><B>Notes:</B> Allows <STRONG>shared_ptr</STRONG> objects to be used as keys in
associative containers.</P> associative containers.</P>
</blockquote> </blockquote>
<P><EM>[<STRONG>Operator&lt;</STRONG> has been preferred over a <STRONG>std::less </STRONG> <P><EM>[<STRONG>Operator&lt;</STRONG> has been preferred over a <STRONG>std::less </STRONG>
specialization for consistency and legality reasons, as <STRONG>std::less</STRONG> specialization for consistency and legality reasons, as <STRONG>std::less</STRONG>
is required to return the results of <STRONG>operator&lt;</STRONG>, and many is required to return the results of <STRONG>operator&lt;</STRONG>, and many
standard algorithms use <STRONG>operator&lt;</STRONG> instead of <STRONG>std::less</STRONG> standard algorithms use <STRONG>operator&lt;</STRONG> instead of <STRONG>std::less</STRONG>
for comparisons when a predicate is not supplied. Composite objects, like <STRONG>std::pair</STRONG>, for comparisons when a predicate is not supplied. Composite objects, like <STRONG>std::pair</STRONG>,
also implement their <STRONG>operator&lt;</STRONG> in terms of their contained also implement their <STRONG>operator&lt;</STRONG> in terms of their contained
subobjects' <STRONG>operator&lt;</STRONG>.</EM></P> subobjects' <STRONG>operator&lt;</STRONG>.</EM></P>
<P><EM>The rest of the comparison operators are omitted by design.]</EM></P> <P><EM>The rest of the comparison operators are omitted by design.]</EM></P>
<h3><a name="free-swap">swap</a></h3> <h3><a name="free-swap">swap</a></h3>
@@ -443,11 +448,11 @@ q = p;
<BLOCKQUOTE> <BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P> <P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P>
<P><B>Throws:</B> nothing.</P> <P><B>Throws:</B> nothing.</P>
<P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to <P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to
generic programming.</P> generic programming.</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><EM>[<STRONG>swap</STRONG> is defined in the same namespace as <STRONG>shared_ptr</STRONG> <P><EM>[<STRONG>swap</STRONG> is defined in the same namespace as <STRONG>shared_ptr</STRONG>
as this is currently the only legal way to supply a <STRONG>swap</STRONG> function as this is currently the only legal way to supply a <STRONG>swap</STRONG> function
that has a chance to be used by the standard library.]</EM></P> that has a chance to be used by the standard library.]</EM></P>
<h3><a name="get_pointer">get_pointer</a></h3> <h3><a name="get_pointer">get_pointer</a></h3>
<pre>template&lt;class T&gt; <pre>template&lt;class T&gt;
@@ -464,13 +469,13 @@ q = p;
<BLOCKQUOTE> <BLOCKQUOTE>
<P><STRONG>Requires:</STRONG> The expression <code>static_cast&lt;T*&gt;(r.get())</code> <P><STRONG>Requires:</STRONG> The expression <code>static_cast&lt;T*&gt;(r.get())</code>
must be well-formed.</P> must be well-formed.</P>
<P><B>Returns:</B> If <b>r</b> is <i>empty</i>, an <i>empty</i> <b>shared_ptr&lt;T&gt;</b>; <P><B>Returns:</B> If <b>r</b> is <i>empty</i>, an <i>empty</i> <b>shared_ptr&lt;T&gt;</b>;
otherwise, a <STRONG>shared_ptr&lt;T&gt;</STRONG> object that stores a copy of <code> otherwise, a <STRONG>shared_ptr&lt;T&gt;</STRONG> object that stores a copy of <code>
static_cast&lt;T*&gt;(r.get())</code> and <i>shares ownership</i> with <b>r</b>.</P> static_cast&lt;T*&gt;(r.get())</code> and <i>shares ownership</i> with <b>r</b>.</P>
<P><B>Throws:</B> nothing.</P> <P><B>Throws:</B> nothing.</P>
<P><B>Notes:</B> the seemingly equivalent expression</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><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 <p>will eventually result in undefined behavior, attempting to delete the same
object twice.</p> object twice.</p>
</BLOCKQUOTE> </BLOCKQUOTE>
<h3><a name="const_pointer_cast">const_pointer_cast</a></h3> <h3><a name="const_pointer_cast">const_pointer_cast</a></h3>
@@ -479,13 +484,13 @@ q = p;
<BLOCKQUOTE> <BLOCKQUOTE>
<P><STRONG>Requires:</STRONG> The expression <code>const_cast&lt;T*&gt;(r.get())</code> <P><STRONG>Requires:</STRONG> The expression <code>const_cast&lt;T*&gt;(r.get())</code>
must be well-formed.</P> must be well-formed.</P>
<P><B>Returns:</B> If <b>r</b> is <i>empty</i>, an <i>empty</i> <b>shared_ptr&lt;T&gt;</b>; <P><B>Returns:</B> If <b>r</b> is <i>empty</i>, an <i>empty</i> <b>shared_ptr&lt;T&gt;</b>;
otherwise, a <STRONG>shared_ptr&lt;T&gt;</STRONG> object that stores a copy of <code> otherwise, a <STRONG>shared_ptr&lt;T&gt;</STRONG> object that stores a copy of <code>
const_cast&lt;T*&gt;(r.get())</code> and <i>shares ownership</i> with <b>r</b>.</P> const_cast&lt;T*&gt;(r.get())</code> and <i>shares ownership</i> with <b>r</b>.</P>
<P><B>Throws:</B> nothing.</P> <P><B>Throws:</B> nothing.</P>
<P><B>Notes:</B> the seemingly equivalent expression</P> <P><B>Notes:</B> the seemingly equivalent expression</P>
<p><code>shared_ptr&lt;T&gt;(const_cast&lt;T*&gt;(r.get()))</code></p> <p><code>shared_ptr&lt;T&gt;(const_cast&lt;T*&gt;(r.get()))</code></p>
<p>will eventually result in undefined behavior, attempting to delete the same <p>will eventually result in undefined behavior, attempting to delete the same
object twice.</p> object twice.</p>
</BLOCKQUOTE> </BLOCKQUOTE>
<h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3> <h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3>
@@ -498,14 +503,14 @@ q = p;
<UL> <UL>
<LI> <LI>
When <CODE>dynamic_cast&lt;T*&gt;(r.get())</CODE> returns a nonzero value, a <STRONG> When <CODE>dynamic_cast&lt;T*&gt;(r.get())</CODE> returns a nonzero value, a <STRONG>
shared_ptr&lt;T&gt;</STRONG> object that stores a copy of it and <i>shares shared_ptr&lt;T&gt;</STRONG> object that stores a copy of it and <i>shares
ownership</i> with <STRONG>r</STRONG>; ownership</i> with <STRONG>r</STRONG>;
<LI> <LI>
Otherwise, an <i>empty</i> <STRONG>shared_ptr&lt;T&gt;</STRONG> object.</LI></UL> Otherwise, an <i>empty</i> <STRONG>shared_ptr&lt;T&gt;</STRONG> object.</LI></UL>
<P><B>Throws:</B> nothing.</P> <P><B>Throws:</B> nothing.</P>
<P><B>Notes:</B> the seemingly equivalent expression</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><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 <P>will eventually result in undefined behavior, attempting to delete the same
object twice.</P> object twice.</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<h3><a name="insertion-operator">operator&lt;&lt;</a></h3> <h3><a name="insertion-operator">operator&lt;&lt;</a></h3>
@@ -520,41 +525,41 @@ q = p;
D * get_deleter(shared_ptr&lt;T&gt; const &amp; p);</pre> D * get_deleter(shared_ptr&lt;T&gt; const &amp; p);</pre>
<BLOCKQUOTE> <BLOCKQUOTE>
<P><B>Returns:</B> If <STRONG>*this</STRONG> <EM>owns</EM> a deleter <STRONG>d</STRONG> <P><B>Returns:</B> If <STRONG>*this</STRONG> <EM>owns</EM> a deleter <STRONG>d</STRONG>
of type (cv-unqualified) <STRONG>D</STRONG>, returns <code>&amp;d</code>; of type (cv-unqualified) <STRONG>D</STRONG>, returns <code>&amp;d</code>;
otherwise returns 0.</P> otherwise returns 0.</P>
<P><B>Throws:</B> nothing.</P> <P><B>Throws:</B> nothing.</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<h2><a name="example">Example</a></h2> <h2><a name="example">Example</a></h2>
<p>See <A href="example/shared_ptr_example.cpp">shared_ptr_example.cpp</A> for a <p>See <A href="example/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> complete example program. The program builds a <b>std::vector</b> and <b>std::set</b>
of <b>shared_ptr</b> objects.</p> of <b>shared_ptr</b> objects.</p>
<p>Note that after the containers have been populated, some of the <b>shared_ptr</b> <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 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 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 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 various times while <b>push_back</b> and <b>insert</b> container operations are
performed. More complicated yet, the container operations may throw exceptions performed. More complicated yet, the container operations may throw exceptions
under a variety of circumstances. Getting the memory management and exception 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> handling in this example right without a smart pointer would be a nightmare.</p>
<h2><a name="Handle/Body">Handle/Body</a> Idiom</h2> <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 <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 pimpl) idiom which avoids exposing the body (implementation) in the header
file.</p> file.</p>
<p>The <A href="example/shared_ptr_example2_test.cpp">shared_ptr_example2_test.cpp</A> <p>The <A href="example/shared_ptr_example2_test.cpp">shared_ptr_example2_test.cpp</A>
sample program includes a header file, <A href="example/shared_ptr_example2.hpp">shared_ptr_example2.hpp</A>, sample program includes a header file, <A href="example/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 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 implementation. The instantiation of member functions which require a complete
type occurs in the <A href="example/shared_ptr_example2.cpp">shared_ptr_example2.cpp</A> type occurs in the <A href="example/shared_ptr_example2.cpp">shared_ptr_example2.cpp</A>
implementation file. Note that there is no need for an explicit destructor. 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 Unlike ~scoped_ptr, ~shared_ptr does not require that <b>T</b> be a complete
type.</p> type.</p>
<h2><a name="ThreadSafety">Thread Safety</a></h2> <h2><a name="ThreadSafety">Thread Safety</a></h2>
<p><STRONG>shared_ptr</STRONG> objects offer the same level of thread safety as <p><STRONG>shared_ptr</STRONG> objects offer the same level of thread safety as
built-in types. A <STRONG>shared_ptr</STRONG> instance can be "read" (accessed built-in types. A <STRONG>shared_ptr</STRONG> instance can be "read" (accessed
using only const operations) simultaneously by multiple threads. Different <STRONG>shared_ptr</STRONG> using only const operations) simultaneously by multiple threads. Different <STRONG>shared_ptr</STRONG>
instances can be "written to" (accessed using mutable operations such as <STRONG>operator= instances can be "written to" (accessed using mutable operations such as <STRONG>operator=
</STRONG>or <STRONG>reset</STRONG>) simultaneosly by multiple threads (even </STRONG>or <STRONG>reset</STRONG>) simultaneosly by multiple threads (even
when these instances are copies, and share the same reference count when these instances are copies, and share the same reference count
underneath.)</p> underneath.)</p>
<P>Any other simultaneous accesses result in undefined behavior.</P> <P>Any other simultaneous accesses result in undefined behavior.</P>
<P>Examples:</P> <P>Examples:</P>
@@ -601,7 +606,7 @@ p3.reset(new int(1));
p3.reset(new int(2)); // undefined, multiple writes p3.reset(new int(2)); // undefined, multiple writes
</pre> </pre>
<p>&nbsp;</p> <p>&nbsp;</p>
<P>Starting with Boost release 1.33.0, <STRONG>shared_ptr</STRONG> uses a lock-free <P>Starting with Boost release 1.33.0, <STRONG>shared_ptr</STRONG> uses a lock-free
implementation on the following platforms:</P> implementation on the following platforms:</P>
<UL> <UL>
<LI> <LI>
@@ -614,75 +619,75 @@ p3.reset(new int(2)); // undefined, multiple writes
GNU GCC on PowerPC; GNU GCC on PowerPC;
<LI> <LI>
Windows.</LI></UL> Windows.</LI></UL>
<P>If your program is single-threaded and does not link to any libraries that might <P>If your program is single-threaded and does not link to any libraries that might
have used <STRONG>shared_ptr</STRONG> in its default configuration, you can <STRONG> have used <STRONG>shared_ptr</STRONG> in its default configuration, you can <STRONG>
#define</STRONG> the macro <STRONG>BOOST_SP_DISABLE_THREADS</STRONG> on a #define</STRONG> the macro <STRONG>BOOST_SP_DISABLE_THREADS</STRONG> on a
project-wide basis to switch to ordinary non-atomic reference count updates.</P> project-wide basis to switch to ordinary non-atomic reference count updates.</P>
<P>(Defining <STRONG>BOOST_SP_DISABLE_THREADS</STRONG> in some, but not all, <P>(Defining <STRONG>BOOST_SP_DISABLE_THREADS</STRONG> in some, but not all,
translation units is technically a violation of the One Definition Rule and translation units is technically a violation of the One Definition Rule and
undefined behavior. Nevertheless, the implementation attempts to do its best to undefined behavior. Nevertheless, the implementation attempts to do its best to
accommodate the request to use non-atomic updates in those translation units. accommodate the request to use non-atomic updates in those translation units.
No guarantees, though.)</P> No guarantees, though.)</P>
<P>You can define the macro <STRONG>BOOST_SP_USE_PTHREADS</STRONG> to turn off the <P>You can define the macro <STRONG>BOOST_SP_USE_PTHREADS</STRONG> to turn off the
lock-free platform-specific implementation and fall back to the generic <STRONG>pthread_mutex_t</STRONG>-based lock-free platform-specific implementation and fall back to the generic <STRONG>pthread_mutex_t</STRONG>-based
code.</P> code.</P>
<h2><a name="FAQ">Frequently Asked Questions</a></h2> <h2><a name="FAQ">Frequently Asked Questions</a></h2>
<P><B>Q.</B> There are several variations of shared pointers, with different <P><B>Q.</B> There are several variations of shared pointers, with different
tradeoffs; why does the smart pointer library supply only a single 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 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?</P> as to find the most suitable for the job at hand?</P>
<P> <P>
<b>A.</b> An important goal of <STRONG>shared_ptr</STRONG> is to provide a <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 standard shared-ownership pointer. Having a single pointer type is important
for stable library interfaces, since different shared pointers typically cannot for stable library interfaces, since different shared pointers typically cannot
interoperate, i.e. a reference counted pointer (used by library A) cannot share interoperate, i.e. a reference counted pointer (used by library A) cannot share
ownership with a linked pointer (used by library B.)<BR> ownership with a linked pointer (used by library B.)<BR>
</P> </P>
<P><B>Q.</B> Why doesn't <B>shared_ptr</B> have template parameters supplying <P><B>Q.</B> Why doesn't <B>shared_ptr</B> have template parameters supplying
traits or policies to allow extensive user customization?</P> traits or policies to allow extensive user customization?</P>
<P> <P>
<B>A.</B> Parameterization discourages users. The <B>shared_ptr</B> template is <B>A.</B> Parameterization discourages users. The <B>shared_ptr</B> template is
carefully crafted to meet common needs without extensive parameterization. Some carefully crafted to meet common needs without extensive parameterization. Some
day a highly configurable smart pointer may be invented that is also very easy 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 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 pointer of choice for a wide range of applications. (Those interested in policy
based smart pointers should read <A href="http://www.awprofessional.com/bookstore/product.asp?isbn=0201704315&amp;rl=1"> based smart pointers should read <A href="http://www.awprofessional.com/bookstore/product.asp?isbn=0201704315&amp;rl=1">
Modern C++ Design</A> by Andrei Alexandrescu.)<BR> Modern C++ Design</A> by Andrei Alexandrescu.)<BR>
</P> </P>
<P><B>Q.</B> I am not convinced. Default parameters can be used where appropriate <P><B>Q.</B> I am not convinced. Default parameters can be used where appropriate
to hide the complexity. Again, why not policies?</P> to hide the complexity. Again, why not policies?</P>
<P> <P>
<B>A.</B> Template parameters affect the type. See the answer to the first <B>A.</B> Template parameters affect the type. See the answer to the first
question above.<BR> question above.<BR>
</P> </P>
<P><B>Q.</B> Why doesn't <b>shared_ptr</b> use a linked list implementation?</P> <P><B>Q.</B> Why doesn't <b>shared_ptr</b> use a linked list implementation?</P>
<P> <P>
<b>A.</b> A linked list implementation does not offer enough advantages to <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> 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 page. In addition, it is expensive to make a linked list implementation thread
safe.<BR> safe.<BR>
</P> </P>
<P><b>Q.</b> Why doesn't <b>shared_ptr</b> (or any of the other Boost smart <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>?</P> pointers) supply an automatic conversion to <b>T*</b>?</P>
<P> <P>
<b>A.</b> Automatic conversion is believed to be too error prone.<BR> <b>A.</b> Automatic conversion is believed to be too error prone.<BR>
</P> </P>
<P><B>Q.</B> Why does <b>shared_ptr</b> supply use_count()?</P> <P><B>Q.</B> Why does <b>shared_ptr</b> supply use_count()?</P>
<P> <P>
<b>A.</b> As an aid to writing test cases and debugging displays. One of the <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 progenitors had use_count(), and it was useful in tracking down bugs in a
complex project that turned out to have cyclic-dependencies.<BR> complex project that turned out to have cyclic-dependencies.<BR>
</P> </P>
<P><B>Q.</B> Why doesn't <b>shared_ptr</b> specify complexity requirements?</P> <P><B>Q.</B> Why doesn't <b>shared_ptr</b> specify complexity requirements?</P>
<P> <P>
<b>A.</b> Because complexity requirements limit implementors and complicate the <b>A.</b> Because complexity requirements limit implementors and complicate the
specification without apparent benefit to <b>shared_ptr</b> users. For example, specification without apparent benefit to <b>shared_ptr</b> users. For example,
error-checking implementations might become non-conforming if they had to meet error-checking implementations might become non-conforming if they had to meet
stringent complexity requirements.<BR> stringent complexity requirements.<BR>
</P> </P>
<P><b>Q.</b> Why doesn't <b>shared_ptr</b> provide a release() function?</P> <P><b>Q.</b> Why doesn't <b>shared_ptr</b> provide a release() function?</P>
<P> <P>
<b>A.</b> <b>shared_ptr</b> cannot give away ownership unless it's unique() <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> because the other copy will still destroy the object.</P>
<p>Consider:</p> <p>Consider:</p>
<blockquote><pre>shared_ptr&lt;int&gt; a(new int); <blockquote><pre>shared_ptr&lt;int&gt; a(new int);
@@ -692,25 +697,25 @@ int * p = a.release();
// Who owns p now? b will still call delete on it in its destructor.</pre> // Who owns p now? b will still call delete on it in its destructor.</pre>
</blockquote> </blockquote>
<p>Furthermore, the pointer returned by <code>release()</code> would be difficult <p>Furthermore, the pointer returned by <code>release()</code> would be difficult
to deallocate reliably, as the source <b>shared_ptr</b> could have been created to deallocate reliably, as the source <b>shared_ptr</b> could have been created
with a custom deleter.<BR> with a custom deleter.<BR>
</p> </p>
<P><b>Q.</b> Why is <code>operator-&gt;()</code> const, but its return value is a <P><b>Q.</b> Why is <code>operator-&gt;()</code> const, but its return value is a
non-const pointer to the element type?</P> non-const pointer to the element type?</P>
<P> <P>
<b>A.</b> Shallow copy pointers, including raw pointers, typically don't <b>A.</b> Shallow copy pointers, including raw pointers, typically don't
propagate constness. It makes little sense for them to do so, as you can always propagate constness. It makes little sense for them to do so, as you can always
obtain a non-const pointer from a const one and then proceed to modify the obtain a non-const pointer from a const one and then proceed to modify the
object through it.<b>shared_ptr</b> is "as close to raw pointers as possible object through it.<b>shared_ptr</b> is "as close to raw pointers as possible
but no closer".<BR> but no closer".<BR>
<BR> <BR>
</P> </P>
<hr> <hr>
<p> <p>
$Date$</p> $Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License,
Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body> </body>

View File

@@ -14,15 +14,15 @@
<a href="#History">History and Acknowledgements</a><br> <a href="#History">History and Acknowledgements</a><br>
<a href="#References">References</a></p> <a href="#References">References</a></p>
<h2><a name="Introduction">Introduction</a></h2> <h2><a name="Introduction">Introduction</a></h2>
<p>Smart pointers are objects which store pointers to dynamically allocated (heap) <p>Smart pointers are objects which store pointers to dynamically allocated (heap)
objects. They behave much like built-in C++ pointers except that they objects. They behave much like built-in C++ pointers except that they
automatically delete the object pointed to at the appropriate time. Smart automatically delete the object pointed to at the appropriate time. Smart
pointers are particularly useful in the face of exceptions as they ensure pointers are particularly useful in the face of exceptions as they ensure
proper destruction of dynamically allocated objects. They can also be used to proper destruction of dynamically allocated objects. They can also be used to
keep track of dynamically allocated objects shared by multiple owners.</p> keep track of dynamically allocated objects shared by multiple owners.</p>
<p>Conceptually, smart pointers are seen as owning the object pointed to, and thus <p>Conceptually, smart pointers are seen as owning the object pointed to, and thus
responsible for deletion of the object when it is no longer needed.</p> responsible for deletion of the object when it is no longer needed.</p>
<p>The smart pointer library provides five smart pointer class templates:</p> <p>The smart pointer library provides six smart pointer class templates:</p>
<div align="left"> <div align="left">
<table border="1" cellpadding="4" cellspacing="0"> <table border="1" cellpadding="4" cellspacing="0">
<tr> <tr>
@@ -38,7 +38,7 @@
<tr> <tr>
<td><a href="shared_ptr.htm"><b>shared_ptr</b></a></td> <td><a href="shared_ptr.htm"><b>shared_ptr</b></a></td>
<td><a href="../../boost/shared_ptr.hpp">&lt;boost/shared_ptr.hpp&gt;</a></td> <td><a href="../../boost/shared_ptr.hpp">&lt;boost/shared_ptr.hpp&gt;</a></td>
<td>Object ownership shared among multiple pointers</td> <td>Object ownership shared among multiple pointers.</td>
</tr> </tr>
<tr> <tr>
<td><a href="shared_array.htm"><b>shared_array</b></a></td> <td><a href="shared_array.htm"><b>shared_array</b></a></td>
@@ -58,126 +58,137 @@
</table> </table>
</div> </div>
<p>These templates are designed to complement the <b>std::auto_ptr</b> template.</p> <p>These templates are designed to complement the <b>std::auto_ptr</b> template.</p>
<p>They are examples of the "resource acquisition is initialization" idiom <p>They are examples of the "resource acquisition is initialization" idiom
described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition, described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition,
Section 14.4, Resource Management.</p> Section 14.4, Resource Management.</p>
<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is <p>Additionally, the smart pointer library provides efficient factory functions
for creating <code>shared_ptr</code> objects:</p>
<div align="left">
<table border="1" cellpadding="4" cellspacing="0">
<tr>
<td><a href="make_shared.html"><b>make_shared and allocate_shared</b></a></td>
<td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</a></td>
<td>Efficient creation of <code>shared_ptr</code> objects.</td>
</tr>
</table>
</div>
<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is
provided to verify correct operation.</p> provided to verify correct operation.</p>
<p>A page on <a href="compatibility.htm">compatibility</a> with older versions of <p>A page on <a href="compatibility.htm">compatibility</a> with older versions of
the Boost smart pointer library describes some of the changes since earlier the Boost smart pointer library describes some of the changes since earlier
versions of the smart pointer implementation.</p> versions of the smart pointer implementation.</p>
<p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest <p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest
to those curious about performance issues.</p> to those curious about performance issues.</p>
<P>A page on <A href="sp_techniques.html">smart pointer programming techniques</A> lists <P>A page on <A href="sp_techniques.html">smart pointer programming techniques</A> lists
some advanced applications of <code>shared_ptr</code> and <code>weak_ptr</code>.</P> some advanced applications of <code>shared_ptr</code> and <code>weak_ptr</code>.</P>
<h2><a name="common_requirements">Common Requirements</a></h2> <h2><a name="common_requirements">Common Requirements</a></h2>
<p>These smart pointer class templates have a template parameter, <b>T</b>, which <p>These smart pointer class templates have a template parameter, <b>T</b>, which
specifies the type of the object pointed to by the smart pointer. The behavior specifies the type of the object pointed to by the smart pointer. The behavior
of the smart pointer templates is undefined if the destructor or <b>operator delete</b> of the smart pointer templates is undefined if the destructor or <b>operator delete</b>
for objects of type <b>T</b> throw exceptions.</p> for objects of type <b>T</b> throw exceptions.</p>
<p><b>T</b> may be an incomplete type at the point of smart pointer declaration. <p><b>T</b> may be an incomplete type at the point of smart pointer declaration.
Unless otherwise specified, it is required that <b>T</b> be a complete type at Unless otherwise specified, it is required that <b>T</b> be a complete type at
points of smart pointer instantiation. Implementations are required to diagnose points of smart pointer instantiation. Implementations are required to diagnose
(treat as an error) all violations of this requirement, including deletion of (treat as an error) all violations of this requirement, including deletion of
an incomplete type. See the description of the <a href="../utility/utility.htm#checked_delete"> an incomplete type. See the description of the <a href="../utility/utility.htm#checked_delete">
<b>checked_delete</b></a> function template.</p> <b>checked_delete</b></a> function template.</p>
<P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of <P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of
its member functions do not require <STRONG>T</STRONG> to be a complete type.</P> its member functions do not require <STRONG>T</STRONG> to be a complete type.</P>
<h3>Rationale</h3> <h3>Rationale</h3>
<p>The requirements on <b>T</b> are carefully crafted to maximize safety yet allow <p>The requirements on <b>T</b> are carefully crafted to maximize safety yet allow
handle-body (also called pimpl) and similar idioms. In these idioms a smart handle-body (also called pimpl) and similar idioms. In these idioms a smart
pointer may appear in translation units where <b>T</b> is an incomplete type. pointer may appear in translation units where <b>T</b> is an incomplete type.
This separates interface from implementation and hides implementation from This separates interface from implementation and hides implementation from
translation units which merely use the interface. Examples described in the translation units which merely use the interface. Examples described in the
documentation for specific smart pointers illustrate use of smart pointers in documentation for specific smart pointers illustrate use of smart pointers in
these idioms.</p> these idioms.</p>
<p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at <p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at
destruction time, but <b>shared_ptr</b> does not.</p> destruction time, but <b>shared_ptr</b> does not.</p>
<h2><a name="Exception_Safety">Exception Safety</a></h2> <h2><a name="Exception_Safety">Exception Safety</a></h2>
<p>Several functions in these smart pointer classes are specified as having "no <p>Several functions in these smart pointer classes are specified as having "no
effect" or "no effect except such-and-such" if an exception is thrown. This effect" or "no effect except such-and-such" if an exception is thrown. This
means that when an exception is thrown by an object of one of these classes, means that when an exception is thrown by an object of one of these classes,
the entire program state remains the same as it was prior to the function call the entire program state remains the same as it was prior to the function call
which resulted in the exception being thrown. This amounts to a guarantee that which resulted in the exception being thrown. This amounts to a guarantee that
there are no detectable side effects. Other functions never throw exceptions. there are no detectable side effects. Other functions never throw exceptions.
The only exception ever thrown by functions which do throw (assuming <b>T</b> meets The only exception ever thrown by functions which do throw (assuming <b>T</b> meets
the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>, the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>,
and that is thrown only by functions which are explicitly documented as and that is thrown only by functions which are explicitly documented as
possibly throwing <b>std::bad_alloc</b>.</p> possibly throwing <b>std::bad_alloc</b>.</p>
<h2><a name="Exception-specifications">Exception-specifications</a></h2> <h2><a name="Exception-specifications">Exception-specifications</a></h2>
<p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification"> <p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification">
exception-specification rationale</a>.</p> exception-specification rationale</a>.</p>
<p>All the smart pointer templates contain member functions which can never throw <p>All the smart pointer templates contain member functions which can never throw
exceptions, because they neither throw exceptions themselves nor call other exceptions, because they neither throw exceptions themselves nor call other
functions which may throw exceptions. These members are indicated by a comment: <code> functions which may throw exceptions. These members are indicated by a comment: <code>
// never throws</code>. // never throws</code>.
</p> </p>
<p>Functions which destroy objects of the pointed to type are prohibited from <p>Functions which destroy objects of the pointed to type are prohibited from
throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p> throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p>
<h2><a name="History">History</a> and Acknowledgements</h2> <h2><a name="History">History</a> and Acknowledgements</h2>
<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing <p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>. bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
See the <a href="compatibility.htm">compatibility</a> page for a summary of the See the <a href="compatibility.htm">compatibility</a> page for a summary of the
changes.</p> changes.</p>
<p>May 2001. Vladimir Prus suggested requiring a complete type on destruction. <p>May 2001. Vladimir Prus suggested requiring a complete type on destruction.
Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman
Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and
others.</p> others.</p>
<p>November 1999. Darin Adler provided <b>operator ==</b>, <b>operator !=</b>, and <b>std::swap</b> <p>November 1999. Darin Adler provided <b>operator ==</b>, <b>operator !=</b>, and <b>std::swap</b>
and <b>std::less</b> specializations for shared types.</p> and <b>std::less</b> specializations for shared types.</p>
<p>September 1999. Luis Coelho provided <b>shared_ptr::swap</b> and <b>shared_array::swap</b></p> <p>September 1999. Luis Coelho provided <b>shared_ptr::swap</b> and <b>shared_array::swap</b></p>
<p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a <p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a
number of suggestions resulting in numerous improvements.</p> number of suggestions resulting in numerous improvements.</p>
<p>October 1998. Beman Dawes proposed reviving the original semantics under the <p>October 1998. Beman Dawes proposed reviving the original semantics under the
names <b>safe_ptr</b> and <b>counted_ptr</b>, meeting of Per Andersson, Matt names <b>safe_ptr</b> and <b>counted_ptr</b>, meeting of Per Andersson, Matt
Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar K<EFBFBD>hl, Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar K&uuml;hl,
Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new
class names were finalized, it was decided that there was no need to exactly class names were finalized, it was decided that there was no need to exactly
follow the <b>std::auto_ptr</b> interface, and various function signatures and follow the <b>std::auto_ptr</b> interface, and various function signatures and
semantics were finalized.</p> semantics were finalized.</p>
<p>Over the next three months, several implementations were considered for <b>shared_ptr</b>, <p>Over the next three months, several implementations were considered for <b>shared_ptr</b>,
and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list. and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list.
The implementation questions revolved around the reference count which must be The implementation questions revolved around the reference count which must be
kept, either attached to the pointed to object, or detached elsewhere. Each of kept, either attached to the pointed to object, or detached elsewhere. Each of
those variants have themselves two major variants: those variants have themselves two major variants:
<ul> <ul>
<li> <li>
Direct detached: the shared_ptr contains a pointer to the object, and a pointer Direct detached: the shared_ptr contains a pointer to the object, and a pointer
to the count. to the count.
<li> <li>
Indirect detached: the shared_ptr contains a pointer to a helper object, which Indirect detached: the shared_ptr contains a pointer to a helper object, which
in turn contains a pointer to the object and the count. in turn contains a pointer to the object and the count.
<li> <li>
Embedded attached: the count is a member of the object pointed to. Embedded attached: the count is a member of the object pointed to.
<li> <li>
Placement attached: the count is attached via operator new manipulations.</li> Placement attached: the count is attached via operator new manipulations.</li>
</ul> </ul>
<p>Each implementation technique has advantages and disadvantages. We went so far <p>Each implementation technique has advantages and disadvantages. We went so far
as to run various timings of the direct and indirect approaches, and found that as to run various timings of the direct and indirect approaches, and found that
at least on Intel Pentium chips there was very little measurable difference. at least on Intel Pentium chips there was very little measurable difference.
Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar
K<EFBFBD>hl suggested an elegant partial template specialization technique to allow K&uuml;hl suggested an elegant partial template specialization technique to allow
users to choose which implementation they preferred, and that was also users to choose which implementation they preferred, and that was also
experimented with.</p> experimented with.</p>
<p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage <p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage
users", and in the end we choose to supply only the direct implementation.</p> users", and in the end we choose to supply only the direct implementation.</p>
<p>Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named <b>auto_ptr</b> <p>Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named <b>auto_ptr</b>
and <b>counted_ptr</b> which were very similar to what we now call <b>scoped_ptr</b> and <b>counted_ptr</b> which were very similar to what we now call <b>scoped_ptr</b>
and <b>shared_ptr</b>. <a href="#Col-94">[Col-94]</a> In one of the very few and <b>shared_ptr</b>. <a href="#Col-94">[Col-94]</a> In one of the very few
cases where the Library Working Group's recommendations were not followed by cases where the Library Working Group's recommendations were not followed by
the full committee, <b>counted_ptr</b> was rejected and surprising the full committee, <b>counted_ptr</b> was rejected and surprising
transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p> transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p>
<h2><a name="References">References</a></h2> <h2><a name="References">References</a></h2>
<p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf"> <p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">
Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555, Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555,
July, 1994.</p> July, 1994.</p>
<p>[<a name="E&amp;D-94">E&amp;D-94</a>] John R. Ellis &amp; David L. Detlefs, <a href="http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a"> <p>[<a name="E&amp;D-94">E&amp;D-94</a>] John R. Ellis &amp; David L. Detlefs, <a href="http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a">
Safe, Efficient Garbage Collection for C++</a>, Usenix Proceedings, Safe, Efficient Garbage Collection for C++</a>, Usenix Proceedings,
February, 1994. This paper includes an extensive discussion of weak pointers February, 1994. This paper includes an extensive discussion of weak pointers
and an extensive bibliography.</p> and an extensive bibliography.</p>
<hr> <hr>
<p>$Date$</p> <p>$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Distributed under the Boost Software License, Version 1.0. See accompanying Distributed under the Boost Software License, Version 1.0. See accompanying
file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at
<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>