More documentation fixes reflecting Dave Abrahams' comments

[SVN r15411]
This commit is contained in:
Peter Dimov
2002-09-17 13:59:17 +00:00
parent 0f05f41306
commit 024f918b86
4 changed files with 329 additions and 399 deletions

View File

@ -1,51 +1,38 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head>
<head> <title>scoped_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>scoped_ptr</title> </head>
</head> <body bgcolor="#ffffff" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86"><a name="scoped_ptr">scoped_ptr</a>
<body bgcolor="#FFFFFF" text="#000000"> class template</h1>
<p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86"><a name="scoped_ptr">scoped_ptr</a> class template</h1> object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.)
The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>,
<p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated or via an explicit <b>reset</b>. See the <a href="#example">example</a>.</p>
object. (Dynamically allocated objects are allocated with the C++ <b>new</b> <p>The <b>scoped_ptr</b> template is a simple solution for simple needs. It
expression.) The object pointed to is guaranteed to be deleted, supplies a basic "resource acquisition is initialization" facility, without
either on destruction of the <b>scoped_ptr</b>, or via an explicit <b>reset</b>. shared-ownership or transfer-of-ownership semantics. Both its name and
See the <a href="#example">example</a>.</p> enforcement of semantics (by being <a href="../utility/utility.htm#class noncopyable">
noncopyable</a>) signal its intent to retain ownership solely within the
<p>The <b>scoped_ptr</b> template is a simple solution for simple current scope. Because it is <a href="../utility/utility.htm#class noncopyable">noncopyable</a>,
needs. It supplies a basic &quot;resource acquisition is it is safer than <b>shared_ptr</b> or <b>std::auto_ptr</b> for pointers which
initialization&quot; facility, without shared-ownership or transfer-of-ownership should not be copied.</p>
semantics. Both its name and enforcement of semantics (by being <p>Because <b>scoped_ptr</b> is simple, in its usual implementation every operation
<a href="../utility/utility.htm#class noncopyable">noncopyable</a>) is as fast as for a built-in pointer and it has no more space overhead that a
signal its intent to retain ownership solely within the current scope. built-in pointer.</p>
Because it is <a href="../utility/utility.htm#class noncopyable">noncopyable</a>, it is <p><STRONG>scoped_ptr</STRONG> cannot be used in C++ Standard Library
safer than <b>shared_ptr</b> or <b>std::auto_ptr</b> for pointers which should not be containers. Use <a href="shared_ptr.htm"><b>shared_ptr</b></a> if you need
copied.</p> a smart pointer that can.</p>
<p><STRONG>scoped_ptr</STRONG> cannot correctly hold a pointer to a dynamically
<p>Because <b>scoped_ptr</b> is simple, in its usual implementation allocated array. See <a href="scoped_array.htm"><b>scoped_array</b></a> for
every operation is as fast as for a built-in pointer and it has no more space overhead that usage.</p>
that a built-in pointer.</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">
<p>It cannot be used in C++ Standard Library containers. common requirements</a>.</p>
See <a href="shared_ptr.htm"><b>shared_ptr</b></a> <h2>Synopsis</h2>
or <b>std::auto_ptr</b> if <b>scoped_ptr</b> does not meet your needs.</p> <pre>namespace boost {
<p>It cannot correctly hold a pointer to a
dynamically allocated array. See <a href="scoped_array.htm"><b>scoped_array</b></a>
for that usage.</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>.</p>
<h2>Synopsis</h2>
<pre>namespace boost {
template&lt;typename T&gt; class scoped_ptr : <a href="../utility/utility.htm#class noncopyable">noncopyable</a> { template&lt;typename T&gt; class scoped_ptr : <a href="../utility/utility.htm#class noncopyable">noncopyable</a> {
@ -53,7 +40,7 @@ pointed to. <b>T</b> must meet the smart pointer
typedef T <a href="#element_type">element_type</a>; typedef T <a href="#element_type">element_type</a>;
explicit <a href="#constructors">scoped_ptr</a>(T * p = 0); // never throws explicit <a href="#constructors">scoped_ptr</a>(T * p = 0); // never throws
<a href="#~scoped_ptr">~scoped_ptr</a>(); // never throws <a href="#destructor">~scoped_ptr</a>(); // never throws
void <a href="#reset">reset</a>(T * p = 0); // never throws void <a href="#reset">reset</a>(T * p = 0); // never throws
@ -67,75 +54,59 @@ pointed to. <b>T</b> must meet the smart pointer
template&lt;typename T&gt; void <a href="#free-swap">swap</a>(scoped_ptr&lt;T&gt; &amp; a, scoped_ptr&lt;T&gt; &amp; b); // never throws template&lt;typename T&gt; void <a href="#free-swap">swap</a>(scoped_ptr&lt;T&gt; &amp; a, scoped_ptr&lt;T&gt; &amp; b); // never throws
}</pre> }</pre>
<h2>Members</h2>
<h2>Members</h2> <h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre>
<h3><a name="element_type">element_type</a></h3> <p>Provides the type of the stored pointer.</p>
<pre>typedef T element_type;</pre> <h3><a name="constructors">constructors</a></h3>
<p>Provides the type of the stored pointer.</p> <pre>explicit scoped_ptr(T * p = 0); // never throws</pre>
<p>Constructs a <b>scoped_ptr</b>, storing a copy of <b>p</b>, which must have been
<h3><a name="constructors">constructors</a></h3> allocated via a C++ <b>new</b> expression or be 0. <b>T</b> is not required be
<pre>explicit scoped_ptr(T * p = 0); // never throws</pre> a complete type. See the smart pointer <a href="smart_ptr.htm#Common requirements">common
<p>Constructs a <b>scoped_ptr</b>, storing a copy of <b>p</b>, which must requirements</a>.</p>
have been allocated via a C++ <b>new</b> expression or be 0. <h3><a name="destructor">destructor</a></h3>
<b>T</b> is not required be a complete type. <pre>~scoped_ptr(); // never throws</pre>
See the smart pointer <p>Destroys the object pointed to by the stored pointer, if any, as if by using <tt>delete
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p> this-&gt;get()</tt>.</p>
<P>
<h3><a name="~scoped_ptr">destructor</a></h3> The guarantee that this does not throw exceptions depends on the requirement
<pre>~scoped_ptr(); // never throws</pre> that the deleted object's destructor does not throw exceptions. See the smart
<p>Deletes the object pointed to by the stored pointer. pointer <a href="smart_ptr.htm#Common requirements">common requirements</a>.</P>
Note that <b>delete</b> on a pointer with a value of 0 is harmless. <h3><a name="reset">reset</a></h3>
The guarantee that this does not throw exceptions depends on the requirement that the <pre>void reset(T * p = 0); // never throws</pre>
deleted object's destructor does not throw exceptions. <p>If p is not equal to the stored pointer, deletes the object pointed to by the
See the smart pointer <a href="smart_ptr.htm#Common requirements">common requirements</a>.</p> stored pointer and then stores a copy of p, which must have been allocated via
a C++ <b>new</b> expression or be 0. The guarantee that this does not throw
<h3><a name="reset">reset</a></h3> exceptions depends on the requirement that the deleted object's destructor does
<pre>void reset(T * p = 0); // never throws</pre> not throw exceptions. See the smart pointer <a href="smart_ptr.htm#Common requirements">
<p>If p is not equal to the stored pointer, deletes the object pointed to by the common requirements</a>.</p>
stored pointer and then stores a copy of p, which must have been allocated via a <h3><a name="indirection">indirection</a></h3>
C++ <b>new</b> expression or be 0. <pre>T &amp; operator*() const; // never throws</pre>
The guarantee that this does not throw exceptions depends on the requirement that the <p>Returns a reference to the object pointed to by the stored pointer. Behavior is
deleted object's destructor does not throw exceptions. undefined if the stored pointer is 0.</p>
See the smart pointer <a href="smart_ptr.htm#Common requirements">common requirements</a>.</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="indirection">indirection</a></h3> <h3><a name="get">get</a></h3>
<pre>T &amp; operator*() const; // never throws</pre> <pre>T * get() const; // never throws</pre>
<p>Returns a reference to the object pointed to by the stored pointer. <p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
Behavior is undefined if the stored pointer is 0.</p> pointer <a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
<pre>T * operator-&gt;() const; // never throws</pre> <h3><a name="swap">swap</a></h3>
<p>Returns the stored pointer. Behavior is undefined if the stored pointer is 0.</p> <pre>void swap(scoped_ptr &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
<h3><a name="get">get</a></h3> complete type. See the smart pointer <a href="smart_ptr.htm#Common requirements">common
<pre>T * get() const; // never throws</pre> requirements</a>.</p>
<p>Returns the stored pointer. <h2><a name="functions">Free Functions</a></h2>
<b>T</b> need not be a complete type. <h3><a name="free-swap">swap</a></h3>
See the smart pointer <pre>template&lt;typename T&gt; void swap(scoped_ptr&lt;T&gt; &amp; a, scoped_ptr&lt;T&gt; &amp; b); // never throws</pre>
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p> <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="swap">swap</a></h3> <h2><a name="example">Example</a></h2>
<pre>void swap(scoped_ptr &amp; b); // never throws</pre> <p>Here's an example that uses <b>scoped_ptr</b>.</p>
<p>Exchanges the contents of the two smart pointers. <blockquote>
<b>T</b> need not be a complete type. <pre>#include &lt;boost/scoped_ptr.hpp&gt;
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="free-swap">swap</a></h3>
<pre>template&lt;typename T&gt; void swap(scoped_ptr&lt;T&gt; &amp; a, scoped_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>
<h2><a name="example">Example</a></h2>
<p>Here's an example that uses <b>scoped_ptr</b>.</p>
<blockquote>
<pre>#include &lt;boost/scoped_ptr.hpp&gt;
#include &lt;iostream&gt; #include &lt;iostream&gt;
struct Shoe { ~Shoe() { std::cout &lt;&lt; &quot;Buckle my shoe\n&quot;; } }; struct Shoe { ~Shoe() { std::cout &lt;&lt; "Buckle my shoe\n"; } };
class MyClass { class MyClass {
boost::scoped_ptr&lt;int&gt; ptr; boost::scoped_ptr&lt;int&gt; ptr;
@ -151,67 +122,55 @@ void main()
std::cout &lt;&lt; my_instance.add_one() &lt;&lt; '\n'; std::cout &lt;&lt; my_instance.add_one() &lt;&lt; '\n';
std::cout &lt;&lt; my_instance.add_one() &lt;&lt; '\n'; std::cout &lt;&lt; my_instance.add_one() &lt;&lt; '\n';
}</pre> }</pre>
</blockquote> </blockquote>
<p>The example program produces the beginning of a child's nursery rhyme:</p>
<p>The example program produces the beginning of a child's nursery rhyme:</p> <blockquote>
<pre>1
<blockquote>
<pre>1
2 2
Buckle my shoe</pre> Buckle my shoe</pre>
</blockquote> </blockquote>
<h2>Rationale</h2>
<h2>Rationale</h2> <p>The primary reason to use <b>scoped_ptr</b> rather than <b>auto_ptr</b> is to
let readers of your code know that you intend "resource acquisition is
<p>The primary reason to use <b>scoped_ptr</b> rather than <b>auto_ptr</b> is to let readers initialization" to be applied only for the current scope, and have no intent to
of your code know that you intend "resource acquisition is initialization" to be applied only transfer ownership.</p>
for the current scope, and have no intent to transfer ownership.</p> <p>A secondary reason to use <b>scoped_ptr</b> is to prevent a later maintenance
programmer from adding a function that transfers ownership by returning the <b>auto_ptr</b>,
<p>A secondary reason to use <b>scoped_ptr</b> is to prevent a later maintenance programmer because the maintenance programmer saw <b>auto_ptr</b>, and assumed ownership
from adding a function that transfers ownership by returning the <b>auto_ptr</b>, could safely be transferred.</p>
because the maintenance programmer saw <b>auto_ptr</b>, and assumed ownership could safely <p>Think of <b>bool</b> vs <b>int</b>. We all know that under the covers <b>bool</b>
be transferred.</p> is usually just an <b>int</b>. Indeed, some argued against including <b>bool</b>
in the C++ standard because of that. But by coding <b>bool</b> rather than <b>int</b>,
<p>Think of <b>bool</b> vs <b>int</b>. We all know that under the covers <b>bool</b> is usually you tell your readers what your intent is. Same with <b>scoped_ptr</b>; by
just an <b>int</b>. Indeed, some argued against including <b>bool</b> in the using it you are signaling intent.</p>
C++ standard because of that. But by coding <b>bool</b> rather than <b>int</b>, you tell your readers <p>It has been suggested that <b>scoped_ptr&lt;T&gt;</b> is equivalent to <b>std::auto_ptr&lt;T&gt;
what your intent is. Same with <b>scoped_ptr</b>; by using it you are signaling intent.</p> const</b>. Ed Brey pointed out, however, that <b>reset</b> will not work on
a <b>std::auto_ptr&lt;T&gt; const.</b></p>
<p>It has been suggested that <b>scoped_ptr&lt;T&gt;</b> is equivalent to <h2><a name="Handle/Body">Handle/Body</a> Idiom</h2>
<b>std::auto_ptr&lt;T> const</b>. Ed Brey pointed out, however, that <p>One common usage of <b>scoped_ptr</b> is to implement a handle/body (also called
<b>reset</b> will not work on a <b>std::auto_ptr&lt;T> const.</b></p> pimpl) idiom which avoids exposing the body (implementation) in the header
file.</p>
<h2><a name="Handle/Body">Handle/Body</a> Idiom</h2> <p>The <a href="scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a> sample
program includes a header file, <a href="scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>,
<p>One common usage of <b>scoped_ptr</b> is to implement a handle/body (also which uses a <b>scoped_ptr&lt;&gt;</b> to an incomplete type to hide the
called pimpl) idiom which avoids exposing the body (implementation) in the header implementation. The instantiation of member functions which require a complete
file.</p> type occurs in the <a href="scoped_ptr_example.cpp">scoped_ptr_example.cpp</a> implementation
file.</p>
<p>The <a href="scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a> <h2>Frequently Asked Questions</h2>
sample program includes a header file, <a href="scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>, <p><b>Q</b>. Why doesn't <b>scoped_ptr</b> have a release() member?<br>
which uses a <b>scoped_ptr&lt;&gt;</b> to an incomplete type to hide the <b>A</b>. When reading source code, it is valuable to be able to draw
implementation. The conclusions about program behavior based on the types being used. If <STRONG>scoped_ptr</STRONG>
instantiation of member functions which require a complete type occurs in had a release() member, it would become possible to transfer ownership out of
the <a href="scoped_ptr_example.cpp">scoped_ptr_example.cpp</a> its scope, weakening its role as a way of limiting resource lifetime to a given
implementation file.</p> scope. Use <STRONG>std::auto_ptr</STRONG> where transfer of ownership is
required. (supplied by Dave Abrahams)</p>
<h2>Frequently Asked Questions</h2> <hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
<p><b>Q</b>. Why doesn't <b>scoped_ptr</b> have a release() member?<br> 17 September 2002<!--webbot bot="Timestamp" endspan i-checksum="15110" --></p>
<b>A</b>. Because the point of <b>scoped_ptr</b> is to signal intent, not <p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
to transfer ownership. Use <b>std::auto_ptr</b> if ownership transfer is Copyright 2002 Peter Dimov. Permission to copy, use, modify, sell and
required.</p> distribute this document is granted provided this copyright notice appears in
all copies. This document is provided "as is" without express or implied
<hr> warranty, and with no claim as to its suitability for any purpose.</p>
</body>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->1 February 2002<!--webbot bot="Timestamp" endspan i-checksum="15110" --></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>
</html> </html>

View File

@ -15,13 +15,13 @@
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_array</b> library containers. Comparison operators are supplied so that <b>shared_array</b>
works with the standard library's associative containers.</p> works with the standard library's associative containers.</p>
<p>Normally, a <b>shared_array</b> cannot correctly hold a pointer to a single <p>Normally, a <b>shared_array</b> cannot correctly hold a pointer to an object
dynamically allocated object. See <a href="shared_ptr.htm"><b>shared_ptr</b></a> that has been allocated with the non-array form of <STRONG>new</STRONG>. See <a href="shared_ptr.htm">
for that usage.</p> <b>shared_ptr</b></a> for that usage.</p>
<p>Because the implementation uses reference counting, <b>shared_array</b> will not <p>Because the implementation uses reference counting, cycles of <b>shared_array</b>
work correctly with cyclic data structures. For example, if <b>main()</b> holds instances will not be reclaimed. For example, if <b>main()</b> holds a <b>shared_array</b>
a <b>shared_array</b> to <b>A</b>, which directly or indirectly holds a <b>shared_array</b> to <b>A</b>, which directly or indirectly holds a <b>shared_array</b> back to <b>A</b>,
back to <b>A</b>, <b>A</b>'s use count will be 2. Destruction of the original <b>shared_array</b> <b>A</b>'s use count will be 2. Destruction of the original <b>shared_array</b>
will leave <b>A</b> dangling with a use count of 1.</p> will leave <b>A</b> dangling with a use count of 1.</p>
<p>A <b>shared_ptr</b> to a <b>std::vector</b> is an alternative to a <b>shared_array</b> <p>A <b>shared_ptr</b> to a <b>std::vector</b> is an alternative to a <b>shared_array</b>
that is a bit heavier duty but far more flexible.</p> that is a bit heavier duty but far more flexible.</p>

View File

@ -150,9 +150,12 @@ void bad()
<P><EM>[It might be&nbsp;convenient to relax the requirements on <STRONG>shared_ptr</STRONG>'s <P><EM>[It might be&nbsp;convenient to relax the requirements on <STRONG>shared_ptr</STRONG>'s
signature, allowing an additional, defaulted, template parameter; the parameter signature, allowing an additional, defaulted, template parameter; the parameter
can encode the threading model, for example. This would help in detecting can encode the threading model, for example. This would help in detecting
possible ODR violations. On the other hand, using <STRONG>shared_ptr</STRONG> as possible ODR violations.</EM></P>
an argument to a&nbsp;template template parameter requires an exact signature <P><EM> On the other hand, using <STRONG>shared_ptr</STRONG> as an argument to
match.]</EM></P> a&nbsp;template template parameter requires an exact signature match. </EM><EM>Metaprogramming
experts tend to deemphasize template template parameters as they are too
inflexible, but the alternative is typically an std::allocator::rebind-type
"hack".]</EM></P>
<h2><a name="Members">Members</a></h2> <h2><a name="Members">Members</a></h2>
<h3><a name="element_type">element_type</a></h3> <h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre> <pre>typedef T element_type;</pre>
@ -229,18 +232,18 @@ void bad()
pointer users.</EM><EM>]</EM></P> pointer users.</EM><EM>]</EM></P>
<pre>template&lt;typename Y, typename D&gt; shared_ptr(Y * p, D d);</pre> <pre>template&lt;typename Y, typename D&gt; shared_ptr(Y * p, D d);</pre>
<blockquote> <blockquote>
<p><b>Requirements:</b> <B>p</B> must be convertible to <B>T *</B>. The copy <p><b>Requirements:</b> <B>p</B> must be convertible to <B>T *</B>. <STRONG>D</STRONG>
constructor and destructor of <b>D</b> must not throw. The expression <code>d2(p)</code>, must be <STRONG>CopyConstructible</STRONG>. The copy constructor and destructor
where <STRONG>d2</STRONG> is a copy of <STRONG>d</STRONG>, must be well-formed, of <b>D</b> must not throw. The expression <code>d(p)</code> must be
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>, storing a copy of <b>p</b> and <b>d</b>.</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>Postconditions:</b> <A href="#use_count">use count</A> is 1.</p>
<p><b>Throws:</b> <b>std::bad_alloc</b>.</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>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>,
<code>d2(p)</code> is invoked, where <STRONG>d2</STRONG> is the stored copy of <STRONG> the stored copy of <STRONG>d</STRONG> is invoked with the stored copy of <STRONG>p</STRONG>
d</STRONG>.</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
@ -311,9 +314,10 @@ template&lt;typename Y&gt; shared_ptr &amp; operator=(shared_ptr&lt;Y&gt; const
template&lt;typename Y&gt; shared_ptr &amp; operator=(std::auto_ptr&lt;Y&gt; &amp; r);</pre> template&lt;typename Y&gt; shared_ptr &amp; operator=(std::auto_ptr&lt;Y&gt; &amp; r);</pre>
<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>Notes:</B> The implementation is free to meet the effects (and the implied <P><B>Notes:</B> The use count updates caused by the temporary object construction
guarantees) via different means, without creating a temporary. In particular, and destruction are not considered observable side effects, and the
in the example:</P> implementation is free to meet the effects (and the implied guarantees) via
different means, without creating a temporary. In particular, in the example:</P>
<pre> <pre>
shared_ptr&lt;int&gt; p(new int); shared_ptr&lt;int&gt; p(new int);
shared_ptr&lt;void&gt; q(p); shared_ptr&lt;void&gt; q(p);
@ -322,6 +326,12 @@ q = p;
</pre> </pre>
<p>both assignments may be no-ops.</p> <p>both assignments may be no-ops.</p>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><EM>[Some experts consider the note to be redundant, as it appears to essentially
mirror the "as if" rile. However, experience suggests that when C++ code is
used to describe effects, it is often misinterpreted as required
implementation. In addition, it is not entirely clear whether the "as if" rule
actually applies here, so it's better to be explicit about the possible
optimizations.]</EM></P>
<h3><a name="reset">reset</a></h3> <h3><a name="reset">reset</a></h3>
<pre>void reset();</pre> <pre>void reset();</pre>
<BLOCKQUOTE> <BLOCKQUOTE>
@ -649,7 +659,7 @@ int * p = a.release();
implementation or a linked list implementation, or some other specific implementation or a linked list implementation, or some other specific
implementation. This is not the intent.</p> implementation. This is not the intent.</p>
<hr> <hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan --> <p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->
23 July 2002<!--webbot bot="Timestamp" i-checksum="38439" endspan --></p> 23 July 2002<!--webbot bot="Timestamp" i-checksum="38439" endspan --></p>
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. <p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002 Peter Dimov. Permission to copy, use, modify, sell and Copyright 2002 Peter Dimov. Permission to copy, use, modify, sell and

View File

@ -1,207 +1,168 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head>
<head> <title>Smart Pointers</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Smart Pointers</title> </head>
</head> <body bgcolor="#ffffff" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">Smart
<body bgcolor="#FFFFFF" text="#000000"> Pointers</h1>
<p>Smart pointers are objects which store pointers to dynamically allocated (heap)
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">Smart objects. They behave much like built-in C++ pointers except that they
Pointers</h1> automatically delete the object pointed to at the appropriate time. Smart
pointers are particularly useful in the face of exceptions as they ensure
<p>Smart pointers are objects which store pointers to dynamically allocated proper destruction of dynamically allocated objects. They can also be used to
(heap) objects. They behave much like built-in C++ pointers except that keep track of dynamically allocated objects shared by multiple owners.</p>
they automatically delete the object pointed to at the appropriate <p>Conceptually, smart pointers are seen as owning the object pointed to, and thus
time. Smart pointers are particularly useful in the face of exceptions as responsible for deletion of the object when it is no longer needed.</p>
they ensure proper destruction of dynamically allocated objects. They can also <p>The smart pointer library provides five smart pointer class templates:</p>
be used to keep track of dynamically allocated objects shared by multiple <div align="left">
owners.</p> <table border="1" cellpadding="4" cellspacing="4">
<tr>
<p>Conceptually, smart pointers are seen as owning the object pointed to, and <td><a href="scoped_ptr.htm"><b>scoped_ptr</b></a></td>
thus responsible for deletion of the object when it is no longer needed.</p> <td><a href="../../boost/scoped_ptr.hpp">&lt;boost/scoped_ptr.hpp&gt;</a></td>
<td>Simple sole ownership of single objects. Noncopyable.</td>
<p>The smart pointer library provides five smart pointer class templates:</p> </tr>
<tr>
<div align="left"> <td><a href="scoped_array.htm"><b>scoped_array</b></a></td>
<table border="1" cellpadding="4" cellspacing="4"> <td><a href="../../boost/scoped_array.hpp">&lt;boost/scoped_array.hpp&gt;</a></td>
<tr> <td>Simple sole ownership of arrays. Noncopyable.</td>
<td><a href="scoped_ptr.htm"><b>scoped_ptr</b></a></td> </tr>
<td><a href="../../boost/scoped_ptr.hpp">&lt;boost/scoped_ptr.hpp&gt;</a></td> <tr>
<td>Simple sole ownership of single objects. Noncopyable.</td> <td><a href="shared_ptr.htm"><b>shared_ptr</b></a></td>
</tr> <td><a href="../../boost/shared_ptr.hpp">&lt;boost/shared_ptr.hpp&gt;</a></td>
<tr> <td>Object ownership shared among multiple pointers</td>
<td><a href="scoped_array.htm"><b>scoped_array</b></a></td> </tr>
<td><a href="../../boost/scoped_array.hpp">&lt;boost/scoped_array.hpp&gt;</a></td> <tr>
<td>Simple sole ownership of arrays. Noncopyable.</td> <td><a href="shared_array.htm"><b>shared_array</b></a></td>
</tr> <td><a href="../../boost/shared_array.hpp">&lt;boost/shared_array.hpp&gt;</a></td>
<tr> <td>Array ownership shared among multiple pointers.</td>
<td><a href="shared_ptr.htm"><b>shared_ptr</b></a></td> </tr>
<td><a href="../../boost/shared_ptr.hpp">&lt;boost/shared_ptr.hpp&gt;</a></td> <tr>
<td>Object ownership shared among multiple pointers</td> <td><a href="weak_ptr.htm"><b>weak_ptr</b></a></td>
</tr> <td><a href="../../boost/weak_ptr.hpp">&lt;boost/weak_ptr.hpp&gt;</a></td>
<tr> <td>Non-owning observers of an object owned by <b>shared_ptr</b>.</td>
<td><a href="shared_array.htm"><b>shared_array</b></a></td> </tr>
<td><a href="../../boost/shared_array.hpp">&lt;boost/shared_array.hpp&gt;</a></td> </table>
<td>Array ownership shared among multiple pointers.</td> </div>
</tr> <p>These templates are designed to complement the <b>std::auto_ptr</b> template.</p>
<tr> <p>They are examples of the "resource acquisition is initialization" idiom
<td><a href="weak_ptr.htm"><b>weak_ptr</b></a></td> described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition,
<td><a href="../../boost/weak_ptr.hpp">&lt;boost/weak_ptr.hpp&gt;</a></td> Section 14.4, Resource Management.</p>
<td>Non-owning observers of an object owned by <b>shared_ptr</b>.</td> <p>A test program, <a href="smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is provided
</tr> to verify correct operation.</p>
</table> <p>A page on <a href="compatibility.htm">compatibility</a> with older versions of
</div> the Boost smart pointer library describes some of the changes since earlier
versions of the smart pointer implementation.</p>
<p>These templates are designed to complement the <b>std::auto_ptr</b> template.</p> <p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest
to those curious about performance issues.</p>
<p>They are examples of the &quot;resource acquisition is initialization&quot; <h2><a name="Common requirements">Common Requirements</a></h2>
idiom described in Bjarne Stroustrup's &quot;The C++ Programming Language&quot;, <p>These smart pointer class templates have a template parameter, <b>T</b>, which
3rd edition, Section 14.4, Resource Management.</p> 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>
<p>A test program, <a href="smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is for objects of type <b>T</b> throw exceptions.</p>
provided to verify correct operation.</p> <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
<p>A page on <a href="compatibility.htm">compatibility</a> with older versions of points of smart pointer instantiation. Implementations are required to diagnose
the Boost smart pointer library describes some of the changes since earlier versions (treat as an error) all violations of this requirement, including deletion of
of the smart pointer implementation.</p> an incomplete type. See the description of the <a href="../utility/utility.htm#checked_delete">
<b>checked_delete</b></a> function template.</p>
<p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of <P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of
interest to those curious about performance issues.</p> its member functions do not require <STRONG>T</STRONG> to be a complete type.</P>
<h3>Rationale</h3>
<h2><a name="Common requirements">Common Requirements</a></h2> <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
<p>These smart pointer class templates have a template parameter, <b>T</b>, which pointer may appear in translation units where <b>T</b> is an incomplete type.
specifies the type of the object pointed to by the smart pointer. The This separates interface from implementation and hides implementation from
behavior of the smart pointer templates is undefined if the destructor or <b>operator delete</b> translation units which merely use the interface. Examples described in the
for objects of type <b>T</b> throw exceptions.</p> documentation for specific smart pointers illustrate use of smart pointers in
these idioms.</p>
<p><b>T</b> may be an incomplete type at the point of smart pointer <p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at
declaration. Unless otherwise specified, it is required that <b>T</b> destruction time, but <b>shared_ptr</b> does not.</p>
be a complete type at points of smart pointer instantiation. Implementations are <h2>Exception Safety</h2>
required to diagnose (treat as an error) all violations of this requirement, <p>Several functions in these smart pointer classes are specified as having "no
including deletion of an incomplete type. effect" or "no effect except such-and-such" if an exception is thrown. This
See the description of the <a href="../utility/utility.htm#checked_delete"><b>checked_delete</b></a> means that when an exception is thrown by an object of one of these classes,
function template.</p> 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
<h3>Rationale</h3> 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
<p>The requirements on <b>T</b> are carefully crafted to maximize safety the <a href="#Common requirements">common requirements</a>) is <b>std::bad_alloc</b>,
yet allow handle-body (also called pimpl) and similar idioms. In these idioms a and that is thrown only by functions which are explicitly documented as
smart pointer may appear in translation units where <b>T</b> is an possibly throwing <b>std::bad_alloc</b>.</p>
incomplete type. This separates interface from implementation and hides <h2>Exception-specifications</h2>
implementation from translation units which merely use the interface. <p>Exception-specifications are not used; see <a href="../../more/lib_guide.htm#Exception-specification">
Examples described in the documentation for specific smart pointers illustrate exception-specification rationale</a>.</p>
use of smart pointers in these idioms.</p> <p>All the smart pointer templates contain member functions which can never throw
exceptions, because they neither throw exceptions themselves nor call other
<p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type functions which may throw exceptions. These members are indicated by a comment: <code>
at destruction time, but <b>shared_ptr</b> does not.</p> // never throws</code>.
</p>
<h2>Exception Safety</h2> <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>
<p>Several functions in these smart pointer classes are specified as having <h2>History and Acknowledgements</h2>
&quot;no effect&quot; or &quot;no effect except such-and-such&quot; if an <p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
exception is thrown. This means that when an exception is thrown by bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
an object of one of these classes, the entire program state remains the same as See the <a href="compatibility.htm">compatibility</a> page for a summary of the
it was prior to the function call which resulted in the exception being changes.</p>
thrown. This amounts to a guarantee that there are no detectable side <p>May 2001. Vladimir Prus suggested requiring a complete type on destruction.
effects. Other functions never throw exceptions. The only exception Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman
ever thrown by functions which do throw (assuming <b>T</b> meets the Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and
<a href="#Common requirements">common requirements</a>) is <b>std::bad_alloc</b>, others.</p>
and that is thrown only by functions which are explicitly documented as possibly <p>November 1999. Darin Adler provided <b>operator ==</b>, <b>operator !=</b>, and <b>std::swap</b>
throwing <b>std::bad_alloc</b>.</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>
<h2>Exception-specifications</h2> <p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a
number of suggestions resulting in numerous improvements.</p>
<p>Exception-specifications are not used; see <p>October 1998. In 1994 Greg Colvin proposed to the C++ Standards Committee
<a href="../../more/lib_guide.htm#Exception-specification">exception-specification classes named <b>auto_ptr</b> and <b>counted_ptr</b> which were very similar to
rationale</a>.</p> what we now call <b>scoped_ptr</b> and <b>shared_ptr</b>. The committee
document was 94-168/N0555, Exception Safe Smart Pointers. In one of the very
<p>All the smart pointer templates contain member functions which can never throw exceptions, few cases where the Library Working Group's recommendations were not followed
because they neither throw exceptions themselves nor call other functions which by the full committee, <b>counted_ptr</b> was rejected and surprising
may throw exceptions. These members are indicated by a comment: transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p>
<code>// never throws</code>. </p> <p>Beman Dawes proposed reviving the original semantics under the names <b>safe_ptr</b>
and <b>counted_ptr</b> at an October, 1998, meeting of Per Andersson, Matt
<p>Functions which destroy objects of the pointed to type are prohibited from Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar K<>hl,
throwing exceptions by the <a href="#Common requirements">common requirements</a>.</p> Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four
class names were finalized, it was decided that there was no need to exactly
<h2>History and Acknowledgements</h2> follow the <b>std::auto_ptr</b> interface, and various function signatures and
semantics were finalized.</p>
<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing bugs, <p>Over the next three months, several implementations were considered for <b>shared_ptr</b>,
and splitting them into four separate headers, and added <b>weak_ptr</b>. See the and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list.
<a href="compatibility.htm">compatibility</a> page for a summary of the changes.</p> The implementation questions revolved around the reference count which must be
kept, either attached to the pointed to object, or detached elsewhere. Each of
<p>May 2001. Vladimir Prus suggested requiring a complete type on those variants have themselves two major variants:
destruction. Refinement evolved in discussions including Dave Abrahams, <ul>
Greg Colvin, Beman Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, <li>
Shankar Sai, and others.</p> Direct detached: the shared_ptr contains a pointer to the object, and a pointer
to the count.
<p>November 1999. Darin Adler provided <b>operator ==</b>, <b>operator !=</b>, and <b>std::swap</b> <li>
and <b>std::less</b> specializations for shared types.</p> Indirect detached: the shared_ptr contains a pointer to a helper object, which
in turn contains a pointer to the object and the count.
<p>September 1999. Luis Coelho provided <b>shared_ptr::swap</b> and <b>shared_array::swap</b></p> <li>
Embedded attached: the count is a member of the object pointed to.
<p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams <li>
made a number of suggestions resulting in numerous improvements.</p> Placement attached: the count is attached via operator new manipulations.</li>
</ul>
<p>October 1998. In 1994 Greg Colvin proposed to the C++ Standards Committee <p>Each implementation technique has advantages and disadvantages. We went so far
classes named <b>auto_ptr</b> and <b>counted_ptr</b> which as to run various timings of the direct and indirect approaches, and found that
were very similar to what we now call <b>scoped_ptr</b> and <b>shared_ptr</b>. at least on Intel Pentium chips there was very little measurable difference.
The committee document was 94-168/N0555, Exception Safe Smart Pointers. In Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar
one of the very few cases where the Library Working Group's recommendations were K<>hl suggested an elegant partial template specialization technique to allow
not followed by the full committee, <b>counted_ptr</b> was rejected users to choose which implementation they preferred, and that was also
and surprising transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p> experimented with.</p>
<p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage
<p>Beman Dawes proposed reviving the original semantics under the names <b>safe_ptr</b> users", and in the end we choose to supply only the direct implementation.</p>
and <b>counted_ptr</b> at an October, 1998, meeting of Per Andersson, <hr>
Matt Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar <p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan
K<EFBFBD>hl, Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, -->
the four class names were finalized, it was decided that there was no need to 4 February 2002<!--webbot bot="Timestamp" endspan i-checksum="40737"
exactly follow the <b>std::auto_ptr</b> interface, and various
function signatures and semantics were finalized.</p>
<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. The implementation questions revolved around the reference count
which must be kept, either attached to the pointed to object, or detached
elsewhere. Each of those variants have themselves two major variants:
<ul>
<li>Direct detached: the shared_ptr contains a pointer to the object, and a
pointer to the count.</li>
<li>Indirect detached: the shared_ptr contains a pointer to a helper object,
which 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.</li>
<li>Placement attached: the count is attached via operator new manipulations.</li>
</ul>
<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 at least on Intel Pentium chips there was very little measurable
difference. Kevlin Henney provided a paper he wrote on &quot;Counted Body
Techniques.&quot; Dietmar K<>hl suggested an elegant partial template
specialization technique to allow users to choose which implementation they
preferred, and that was also experimented with.</p>
<p>But Greg Colvin and Jerry Schwarz argued that &quot;parameterization will
discourage users&quot;, and in the end we choose to supply only the direct
implementation.</p>
<hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan
-->4 February 2002<!--webbot bot="Timestamp" endspan i-checksum="40737"
--></p> --></p>
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Permission to copy, use, modify, sell and distribute this document is granted
Permission to copy, use, provided this copyright notice appears in all copies. This document is provided
modify, sell and distribute this document is granted provided this copyright "as is" without express or implied warranty, and with no claim as to its
notice appears in all copies. This document is provided &quot;as is&quot; suitability for any purpose.</p>
without express or implied warranty, and with no claim as to its suitability for </body>
any purpose.</p>
</body>
</html> </html>