mirror of
https://github.com/boostorg/smart_ptr.git
synced 2026-04-28 18:13:34 +02:00
weak_ptr documentation updated; still a work in progress.
[SVN r16748]
This commit is contained in:
+57
-35
@@ -8,6 +8,7 @@
|
||||
<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">shared_ptr
|
||||
class template</h1>
|
||||
<p><A href="#Introduction">Introduction</A><br>
|
||||
<A href="#Motivation">Motivation</A><br>
|
||||
<A href="#BestPractices">Best Practices</A><br>
|
||||
<A href="#Synopsis">Synopsis</A><br>
|
||||
<A href="#Members">Members</A><br>
|
||||
@@ -46,6 +47,8 @@
|
||||
to <STRONG>shared_ptr<T const></STRONG>, to <STRONG>shared_ptr<U></STRONG>
|
||||
where <STRONG>U</STRONG> is an accessible base of <STRONG>T</STRONG>, and to <STRONG>
|
||||
shared_ptr<void></STRONG>.</P>
|
||||
<h2><a name="Motivation">Motivation</a></h2>
|
||||
<p>[...]</p>
|
||||
<h2><a name="BestPractices">Best Practices</a></h2>
|
||||
<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>
|
||||
@@ -262,22 +265,11 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r); // never
|
||||
<blockquote>
|
||||
<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>
|
||||
and stores a copy of the pointer stored in <STRONG>r</STRONG>.</p>
|
||||
<p><b>Throws:</b> <b>bad_weak_ptr</b> when <code>r.use_count() == 0</code>.</p>
|
||||
and stores a copy of the pointer stored in <STRONG>r</STRONG>.</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
|
||||
effect.</p>
|
||||
</blockquote>
|
||||
<P><EM>[This constructor is an optional part of the specification; it depends on the
|
||||
existence of <STRONG>weak_ptr</STRONG>. It is true that <STRONG>weak_ptr</STRONG>
|
||||
support imposes overhead on every <STRONG>shared_ptr</STRONG> user, regardless
|
||||
of whether weak pointers are used.</EM></P>
|
||||
<P><EM>On the other hand, cyclic references are a serious problem with all reference
|
||||
counted designs. Not providing a solution within the library is unacceptable;
|
||||
if users are forced to reinvent the weak pointer wheel, there is substantial
|
||||
probability that they will get it wrong, as designing a safe <STRONG>weak_ptr</STRONG>
|
||||
interface is non-trivial.</EM></P>
|
||||
<P><EM>My opinion is that the added functionality is worth the cost. <STRONG>weak_ptr</STRONG>
|
||||
is provided in the reference implementation as a proof of concept.]</EM></P>
|
||||
<pre>template<class Y> shared_ptr(std::auto_ptr<Y> & r);</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Constructs a <B>shared_ptr</B>, as if by storing a copy of <STRONG>r.release()</STRONG>.</P>
|
||||
@@ -580,45 +572,60 @@ p3.reset(new int(2)); // undefined, multiple writes
|
||||
<P><B>Q.</B> There are several variations of shared pointers, with different
|
||||
tradeoffs; why does the smart pointer library supply only a single
|
||||
implementation? It would be useful to be able to experiment with each type so
|
||||
as to find the most suitable for the job at hand?<BR>
|
||||
as to find the most suitable for the job at hand?</P>
|
||||
<P>
|
||||
<b>A.</b> An important goal of <STRONG>shared_ptr</STRONG> is to provide a
|
||||
standard shared-ownership pointer. Having a single pointer type is important
|
||||
for stable library interfaces, since different shared pointers typically cannot
|
||||
interoperate, i.e. a reference counted pointer (used by library A) cannot share
|
||||
ownership with a linked pointer (used by library B.)</P>
|
||||
ownership with a linked pointer (used by library B.)<BR>
|
||||
</P>
|
||||
<P><B>Q.</B> Why doesn't <B>shared_ptr</B> have template parameters supplying
|
||||
traits or policies to allow extensive user customization?<BR>
|
||||
traits or policies to allow extensive user customization?</P>
|
||||
<P>
|
||||
<B>A.</B> Parameterization discourages users. The <B>shared_ptr</B> template is
|
||||
carefully crafted to meet common needs without extensive parameterization. Some
|
||||
day a highly configurable smart pointer may be invented that is also very easy
|
||||
to use and very hard to misuse. Until then, <B>shared_ptr</B> is the smart
|
||||
pointer of choice for a wide range of applications. (Those interested in policy
|
||||
based smart pointers should read <A href="http://cseng.aw.com/book/0,,0201704315,00.html">
|
||||
Modern C++ Design</A> by Andrei Alexandrescu.)</P>
|
||||
Modern C++ Design</A> by Andrei Alexandrescu.)<BR>
|
||||
</P>
|
||||
<P><B>Q.</B> I am not convinced. Default parameters can be used where appropriate
|
||||
to hide the complexity. Again, why not policies?<BR>
|
||||
to hide the complexity. Again, why not policies?</P>
|
||||
<P>
|
||||
<B>A.</B> Template parameters affect the type. See the answer to the first
|
||||
question above.</P>
|
||||
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> use a linked list implementation?<br>
|
||||
question above.<BR>
|
||||
</P>
|
||||
<P><B>Q.</B> Why doesn't <b>shared_ptr</b> use a linked list implementation?</P>
|
||||
<P>
|
||||
<b>A.</b> A linked list implementation does not offer enough advantages to
|
||||
offset the added cost of an extra pointer. See <A href="smarttests.htm">timings</A>
|
||||
page. In addition, it is expensive to make a linked list implementation thread
|
||||
safe.</p>
|
||||
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> (or any of the other Boost smart
|
||||
pointers) supply an automatic conversion to <b>T*</b>?<br>
|
||||
<b>A.</b> Automatic conversion is believed to be too error prone.</p>
|
||||
<p><b>Q.</b> Why does <b>shared_ptr</b> supply use_count()?<br>
|
||||
safe.<BR>
|
||||
</P>
|
||||
<P><b>Q.</b> Why doesn't <b>shared_ptr</b> (or any of the other Boost smart
|
||||
pointers) supply an automatic conversion to <b>T*</b>?</P>
|
||||
<P>
|
||||
<b>A.</b> Automatic conversion is believed to be too error prone.<BR>
|
||||
</P>
|
||||
<P><B>Q.</B> Why does <b>shared_ptr</b> supply use_count()?</P>
|
||||
<P>
|
||||
<b>A.</b> As an aid to writing test cases and debugging displays. One of the
|
||||
progenitors had use_count(), and it was useful in tracking down bugs in a
|
||||
complex project that turned out to have cyclic-dependencies.</p>
|
||||
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> specify complexity requirements?<br>
|
||||
complex project that turned out to have cyclic-dependencies.<BR>
|
||||
</P>
|
||||
<P><B>Q.</B> Why doesn't <b>shared_ptr</b> specify complexity requirements?</P>
|
||||
<P>
|
||||
<b>A.</b> Because complexity requirements limit implementors and complicate the
|
||||
specification without apparent benefit to <b>shared_ptr</b> users. For example,
|
||||
error-checking implementations might become non-conforming if they had to meet
|
||||
stringent complexity requirements.</p>
|
||||
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> provide a release() function?<br>
|
||||
stringent complexity requirements.<BR>
|
||||
</P>
|
||||
<P><b>Q.</b> Why doesn't <b>shared_ptr</b> provide a release() function?</P>
|
||||
<P>
|
||||
<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>
|
||||
<blockquote><pre>shared_ptr<int> a(new int);
|
||||
shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2
|
||||
@@ -627,17 +634,32 @@ int * p = a.release();
|
||||
|
||||
// Who owns p now? b will still call delete on it in its destructor.</pre>
|
||||
</blockquote>
|
||||
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> provide (your pet feature here)?<br>
|
||||
<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
|
||||
with a custom deleter.<BR>
|
||||
</p>
|
||||
<P><b>Q.</b> Why is <code>operator->()</code> const, but its return value is a
|
||||
non-const pointer to the element type?</P>
|
||||
<P>
|
||||
<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
|
||||
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
|
||||
but no closer".<BR>
|
||||
</P>
|
||||
<P><b>Q.</b> Why doesn't <b>shared_ptr</b> provide (your pet feature here)?</P>
|
||||
<P>
|
||||
<b>A.</b> Because (your pet feature here) would mandate a reference counted
|
||||
implementation or a linked list implementation, or some other specific
|
||||
implementation. This is not the intent.</p>
|
||||
implementation. This is not the intent.<BR>
|
||||
</P>
|
||||
<hr>
|
||||
<p>
|
||||
$Date$</p>
|
||||
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||
Copyright 2002, 2003 Peter Dimov. Permission to copy, use, modify, sell
|
||||
and distribute this document is granted provided this copyright notice appears
|
||||
in all copies. This document is provided "as is" without express or implied
|
||||
Copyright 2002, 2003 Peter Dimov. Permission to copy, use, modify, sell and
|
||||
distribute this document is granted provided this copyright notice appears in
|
||||
all copies. This document is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user