weak_ptr documentation updated; still a work in progress.

[SVN r16748]
This commit is contained in:
Peter Dimov
2003-01-04 14:24:14 +00:00
parent 987a7d32fb
commit 3e616752c9
4 changed files with 186 additions and 165 deletions

View File

@ -5,7 +5,7 @@
// shared_ptr.hpp
//
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
// Copyright (c) 2001, 2002, 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.

View File

@ -4,7 +4,7 @@
//
// weak_ptr.hpp
//
// Copyright (c) 2001, 2002 Peter Dimov
// Copyright (c) 2001, 2002, 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
@ -37,7 +37,7 @@ public:
typedef T element_type;
weak_ptr(): px(0), pn()
weak_ptr(): px(0), pn() // never throws in 1.30+
{
}
@ -92,7 +92,7 @@ public:
#endif
void reset()
void reset() // never throws in 1.30+
{
this_type().swap(*this);
}

View File

@ -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&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>
shared_ptr&lt;void&gt;</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&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; 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&nbsp;stored in <STRONG>r</STRONG>.</p>
<p><b>Throws:</b>&nbsp;<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&lt;class Y&gt; shared_ptr(std::auto_ptr&lt;Y&gt; &amp; r);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Constructs a <B>shared_ptr</B>, as if by storing a copy of <STRONG>r.release()</STRONG>.</P>
@ -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&lt;int&gt; a(new int);
shared_ptr&lt;int&gt; 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-&gt;()</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&nbsp;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>

View File

@ -4,32 +4,39 @@
<title>weak_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">weak_ptr
<body text="#000000" bgColor="#ffffff">
<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">weak_ptr
class template</h1>
<p>The <b>weak_ptr</b> class template stores a&nbsp;"weak reference"&nbsp;to an
object that's already managed by a <b>shared_ptr</b>. To access the object, a <STRONG>
weak_ptr</STRONG> can be converted to a <STRONG>shared_ptr</STRONG> using <A href="shared_ptr.htm#constructors">
<p><A href="#Introduction">Introduction</A><br>
<A href="#Motivation">Motivation</A><br>
<A href="#Synopsis">Synopsis</A><br>
<A href="#Members">Members</A><br>
<A href="#functions">Free Functions</A><br>
<A href="#FAQ">Frequently Asked Questions</A>
</p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <b>weak_ptr</b> class template stores a "weak reference" to an object that's
already managed by a <b>shared_ptr</b>. To access the object, a <STRONG>weak_ptr</STRONG>
can be converted to a <STRONG>shared_ptr</STRONG> using <A href="shared_ptr.htm#constructors">
the <STRONG>shared_ptr</STRONG> constructor</A> or the function <STRONG><A href="#make_shared">
make_shared</A></STRONG>. When the last <b>shared_ptr</b> to the object
goes away and the object is deleted,&nbsp;the attempt to obtain a <STRONG>shared_ptr</STRONG>
&nbsp;from the <b>weak_ptr</b> instances that refer to the deleted object will
fail: the constructor will throw an exception of type <STRONG>boost::use_count_is_zero</STRONG>,
and <STRONG>make_shared</STRONG> will return a default constructed (null) <STRONG>shared_ptr</STRONG>.</p>
goes away and the object is deleted, the attempt to obtain a <STRONG>shared_ptr</STRONG>
from the <b>weak_ptr</b> instances that refer to the deleted object will fail:
the constructor will throw an exception of type <STRONG>boost::bad_weak_ptr</STRONG>,
and <STRONG>make_shared</STRONG> will return an <EM>empty</EM> <STRONG>shared_ptr</STRONG>.</p>
<p>Every <b>weak_ptr</b> meets the <b>CopyConstructible</b> and <b>Assignable</b> requirements
of the C++ Standard Library, and so can be used in standard library containers.
Comparison operators are supplied so that <b>weak_ptr</b> works with the
standard library's associative containers.</p>
<P><STRONG>weak_ptr</STRONG> operations never throw&nbsp;exceptions.</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>
<P>Compared to&nbsp;<STRONG>shared_ptr</STRONG>, <STRONG>weak_ptr</STRONG> provides
a very limited subset of operations since accessing its stored pointer is
often&nbsp;dangerous in multithreaded&nbsp;programs, and sometimes unsafe even
within a single thread&nbsp;(that is, it may invoke undefined behavior.)
Consider, for example, this innocent piece of code:</P>
<pre>
shared_ptr&lt;int&gt; p(new int(5));
to.</p>
<P>Compared to <STRONG>shared_ptr</STRONG>, <STRONG>weak_ptr</STRONG> provides a
very limited subset of operations since accessing its stored pointer is often
dangerous in multithreaded programs, and sometimes unsafe even within a single
thread (that is, it may invoke undefined behavior.) Consider, for example, this
innocent piece of code:</P>
<pre>shared_ptr&lt;int&gt; p(new int(5));
weak_ptr&lt;int&gt; q(p);
// some time later
@ -44,13 +51,12 @@ if(int * r = q.get())
is a dangling pointer.</P>
<P>The solution to this problem is to create a temporary <STRONG>shared_ptr</STRONG>
from <STRONG>q</STRONG>:</P>
<pre>
shared_ptr&lt;int&gt; p(new int(5));
<pre>shared_ptr&lt;int&gt; p(new int(5));
weak_ptr&lt;int&gt; q(p);
// some time later
if(shared_ptr&lt;int&gt; r = <a href="#make_shared">make_shared</a>(q))
if(shared_ptr&lt;int&gt; r = <A href="#make_shared" >make_shared</A>(q))
{
// use *r
}
@ -58,45 +64,53 @@ if(shared_ptr&lt;int&gt; r = <a href="#make_shared">make_shared</a>(q))
<p>Now <STRONG>r</STRONG> holds a reference to the object that was pointed by <STRONG>q</STRONG>.
Even if <code>p.reset()</code> is executed in another thread, the object will
stay alive until <STRONG>r</STRONG> goes out of scope (or is reset.)</p>
<h2><a name="Motivation">Motivation</a></h2>
<p>[a mechanism to avoid dangling pointers]</p>
<P>[a way to break shared_ptr cycles]</P>
<P>[weak pointer to this - a technique to obtain a shared_ptr to this from within a
member function]</P>
<P>[map&lt;weak_ptr, ...&gt; - a technique to associate arbitrary data with
shared_ptr managed objects]</P>
<P>[gameobject/tank example]</P>
<P>[cache example]</P>
<P>[comparison: weak_ptr vs observer and other approaches]</P>
<P>[hard to reinvent, subtle implementation, with many pitfalls]</P>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;class T&gt; class weak_ptr {
public:
typedef T <a href="#element_type">element_type</a>;
typedef T <A href="#element_type" >element_type</A>;
<a href="#constructors">weak_ptr</a>();
template&lt;class Y&gt; <a href="#constructors">weak_ptr</a>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
<a href="#destructor">~weak_ptr</a>(); // never throws
<A href="#default-constructor" >weak_ptr</A>();
<a href="#constructors">weak_ptr</a>(weak_ptr const &amp; r); // never throws
template&lt;class Y&gt; <a href="#constructors">weak_ptr</a>(weak_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;class Y&gt; <A href="#constructors" >weak_ptr</A>(shared_ptr&lt;Y&gt; const &amp; r);
<A href="#constructors" >weak_ptr</A>(weak_ptr const &amp; r);
template&lt;class Y&gt; <A href="#constructors" >weak_ptr</A>(weak_ptr&lt;Y&gt; const &amp; r);
weak_ptr &amp; <a href="#assignment">operator=</a>(weak_ptr const &amp; r); // never throws
template&lt;class Y&gt; weak_ptr &amp; <a href="#assignment">operator=</a>(weak_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;class Y&gt; weak_ptr &amp; <a href="#assignment">operator=</a>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
<A href="#destructor" >~weak_ptr</A>();
void <a href="#reset">reset</a>();
T * <a href="#get">get</a>() const; // never throws; deprecated, will disappear
weak_ptr &amp; <A href="#assignment" >operator=</A>(weak_ptr const &amp; r);
template&lt;class Y&gt; weak_ptr &amp; <A href="#assignment" >operator=</A>(weak_ptr&lt;Y&gt; const &amp; r);
template&lt;class Y&gt; weak_ptr &amp; <A href="#assignment" >operator=</A>(shared_ptr&lt;Y&gt; const &amp; r);
long <a href="#use_count">use_count</a>() const; // never throws
bool <a href="#expired">expired</a>() const; // never throws
void <A href="#reset" >reset</A>();
void <a href="#swap">swap</a>(weak_ptr&lt;T&gt; &amp; b); // never throws
long <A href="#use_count" >use_count</A>() const;
bool <A href="#expired" >expired</A>() const;
void <A href="#swap" >swap</A>(weak_ptr&lt;T&gt; &amp; b);
};
template&lt;class T, class U&gt;
bool <a href="#comparison">operator==</a>(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T, class U&gt;
bool <a href="#comparison">operator!=</a>(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T&gt;
bool <a href="#comparison">operator&lt;</a>(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;T&gt; const &amp; b); // never throws
template&lt;class T&gt; void <a href="#free-swap">swap</a>(weak_ptr&lt;T&gt; &amp; a, weak_ptr&lt;T&gt; &amp; b); // never throws
bool <A href="#comparison" >operator&lt;</A>(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;U&gt; const &amp; b);
template&lt;class T&gt;
shared_ptr&lt;T&gt; <a href="#make_shared">make_shared</a>(weak_ptr&lt;T&gt; const &amp; r); // never throws
void <A href="#free-swap" >swap</A>(weak_ptr&lt;T&gt; &amp; a, weak_ptr&lt;T&gt; &amp; b);
template&lt;class T&gt;
shared_ptr&lt;T&gt; <A href="#make_shared" >make_shared</A>(weak_ptr&lt;T&gt; const &amp; r);
}
</pre>
@ -106,49 +120,34 @@ if(shared_ptr&lt;int&gt; r = <a href="#make_shared">make_shared</a>(q))
<blockquote>
<p>Provides the type of the template parameter T.</p>
</blockquote>
<h3><a name="constructors">constructors</a></h3>
<pre> weak_ptr();</pre>
<h3><a name="default-constructor">constructors</a></h3>
<pre>weak_ptr();</pre>
<blockquote>
<p><b>Effects:</b> Constructs a <b>weak_ptr</b>.</p>
<p><b>Postconditions:</b> <A href="#use_count">use count</A> is 0; the stored
pointer is 0.</p>
<p><b>Throws:</b> <b>std::bad_alloc</b>.</p>
<p><b>Exception safety:</b> If an exception is thrown, the constructor has no
effect.</p>
<P><B>Notes:</B> <B>T</B> need not be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
</blockquote>
<pre>template&lt;class Y&gt; weak_ptr</A>(shared_ptr&lt;Y&gt; const &amp; r); // never throws</pre>
<p><b>Effects:</b> Constructs an <EM>empty</EM> <b>weak_ptr</b>.</p>
<p><b>Postconditions:</b> <code>use count() == 0<i>???</i></code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote><a name="constructors"></a>
<pre>template&lt;class Y&gt; weak_ptr</A>(shared_ptr&lt;Y&gt; const &amp; r);
weak_ptr(weak_ptr const &amp; r);
template&lt;class Y&gt; weak_ptr(weak_ptr&lt;Y&gt; const &amp; r);</pre>
<blockquote>
<p><b>Effects:</b> Constructs a <b>weak_ptr</b>, as if by storing a copy of the
<p><b>Effects:</b> If <STRONG>r</STRONG> is <EM>empty</EM>, constructs an <EM>empty</EM>
<STRONG>weak_ptr</STRONG>; otherwise, constructs a <b>weak_ptr</b> that <EM>shares
ownership</EM> with <STRONG>r</STRONG> as if by storing a copy of the
pointer stored in <b>r</b>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> The <a href="#use_count">use count</a> for all copies is
unchanged. When the last <b>shared_ptr</b> is destroyed, the use count and
stored pointer become 0.</P>
</blockquote>
<pre>weak_ptr(weak_ptr const &amp; r); // never throws
template&lt;class Y&gt; weak_ptr(weak_ptr&lt;Y&gt; const &amp; r); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Constructs a <b>weak_ptr</b>, as if by storing a copy of the
pointer stored in <b>r</b>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> The <a href="#use_count">use count</a> for all copies is
unchanged.</P>
</blockquote>
<h3><a name="destructor">destructor</a></h3>
<pre>~weak_ptr(); // never throws</pre>
<pre>~weak_ptr();</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Destroys this <b>weak_ptr</b> but has no effect on the object
its stored pointer points to.</P>
<P><B>Throws:</B> nothing.</P>
<P><B>Notes:</B> <B>T</B> need not be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
</BLOCKQUOTE>
<h3><a name="assignment">assignment</a></h3>
<pre>weak_ptr &amp; <a href="#assignment">operator=</a>(weak_ptr const &amp; r); // never throws
template&lt;class Y&gt; weak_ptr &amp; <a href="#assignment">operator=</a>(weak_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;class Y&gt; weak_ptr &amp; <a href="#assignment">operator=</a>(shared_ptr&lt;Y&gt; const &amp; r); // never throws</pre>
<pre>weak_ptr &amp; <A href="#assignment" >operator=</A>(weak_ptr const &amp; r);
template&lt;class Y&gt; weak_ptr &amp; <A href="#assignment" >operator=</A>(weak_ptr&lt;Y&gt; const &amp; r);
template&lt;class Y&gt; weak_ptr &amp; <A href="#assignment" >operator=</A>(shared_ptr&lt;Y&gt; const &amp; r);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>weak_ptr(r).swap(*this)</code>.</P>
<P><B>Throws:</B> nothing.</P>
@ -160,75 +159,50 @@ template&lt;class Y&gt; weak_ptr &amp; <a href="#assignment">operator=</a>(share
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>weak_ptr().swap(*this)</code>.</P>
</BLOCKQUOTE>
<h3><a name="get">get</a></h3>
<pre>T * get() const; // never throws</pre>
<blockquote>
<p><b>Returns:</b> the stored pointer (0 if all <b>shared_ptr</b> objects for that
pointer are destroyed.)</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> Using <b>get</b> in multithreaded code is dangerous. After the
function returns, the pointed-to object may be destroyed by a different thread,
since the <b>weak_ptr</b> doesn't affect its <b>use_count</b>.</P>
</blockquote>
<P><EM>[<b>get</b> is&nbsp;very error-prone. Even single-threaded code may experience
problems, as the returned pointer may be invalidated at any time, for example,
indirectly by a member function of the pointee.</EM></P>
<P><EM><STRONG>get</STRONG>&nbsp;is deprecated, and it will disappear in a future
release. Do not use it.]</EM></P>
<h3><a name="use_count">use_count</a></h3>
<pre>long use_count() const; // never throws</pre>
<pre>long use_count() const;</pre>
<blockquote>
<p><b>Returns:</b> the number of <b>shared_ptr</b> objects sharing ownership of the
stored pointer.</p>
<p><b>Returns:</b> if <STRONG>*this</STRONG> is <EM>empty</EM>, an unspecified
nonnegative value; otherwise, the number of <b>shared_ptr</b> objects that <EM>share
ownership</EM> with <STRONG>*this</STRONG>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only
for debugging and testing purposes, not for production code. <B>T</B> need not
be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
for debugging and testing purposes, not for production code.</P>
</blockquote>
<h3><a name="expired">expired</a></h3>
<pre>bool expired() const; // never throws</pre>
<pre>bool expired() const;</pre>
<blockquote>
<p><b>Returns:</b> <code>use_count() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <code>expired()</code> may be faster than <code>use_count()</code>.
<B>T</B> need not be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
<P><B>Notes:</B> <code>expired()</code> may be faster than <code>use_count()</code>.</P>
</blockquote>
<h3><a name="swap">swap</a></h3>
<pre>void swap(weak_ptr &amp; b); // never throws</pre>
<pre>void swap(weak_ptr &amp; b);</pre>
<blockquote>
<p><b>Effects:</b> Exchanges the contents of the two smart pointers.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <B>T</B> need not be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
</blockquote>
<h2><a name="functions">Free Functions</a></h2>
<h3><a name="comparison">comparison</a></h3>
<pre>template&lt;class T, class U&gt;
bool operator==(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T, class U&gt;
bool operator!=(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;U&gt; const &amp; b); // never throws</pre>
bool operator&lt;(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;U&gt; const &amp; b);</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() == b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <B>T</B> need not be a complete type. See the smart pointer <A href="smart_ptr.htm#Common requirements">
common requirements</A>.</P>
</blockquote>
<pre>template&lt;class T&gt;
bool operator&lt;(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;T&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> an implementation-defined value such that <b>operator&lt;</b> is
a strict weak ordering as described in section 25.3 <code>[lib.alg.sorting]</code>
of the C++ standard.</p>
<p><b>Returns:</b> an unspecified value such that</p>
<UL>
<LI>
<b>operator&lt;</b> is a strict weak ordering as described in section 25.3 <code>[lib.alg.sorting]</code>
of the C++ standard;
<LI>
under the equivalence relation defined by <STRONG>operator&lt;</STRONG>, <code>!(a
&lt; b) &amp;&amp; !(b &lt; a)</code>, two <STRONG>weak_ptr</STRONG> instances
are equivalent if and only if they <EM>share ownership</EM>.</LI></UL>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> Allows <STRONG>weak_ptr</STRONG> objects to be used as keys in
associative containers. <B>T</B> need not be a complete type. See the smart
pointer <A href="smart_ptr.htm#Common requirements">common requirements</A>.</P>
associative containers.</P>
</blockquote>
<h3><a name="free-swap">swap</a></h3>
<pre>template&lt;class T&gt;
void swap(weak_ptr&lt;T&gt; &amp; a, weak_ptr&lt;T&gt; &amp; b) // never throws</pre>
void swap(weak_ptr&lt;T&gt; &amp; a, weak_ptr&lt;T&gt; &amp; b)</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P>
<P><B>Throws:</B> nothing.</P>
@ -237,19 +211,44 @@ template&lt;class T, class U&gt;
</BLOCKQUOTE>
<h3><a name="make_shared">make_shared</a></h3>
<pre>template&lt;class T&gt;
shared_ptr&lt;T&gt; make_shared(weak_ptr&lt;T&gt; &amp; const r) // never throws</pre>
shared_ptr&lt;T&gt; make_shared(weak_ptr&lt;T&gt; &amp; const r)</pre>
<BLOCKQUOTE>
<P><B>Returns:</B> <code>r.expired()? shared_ptr&lt;T&gt;(): shared_ptr&lt;T&gt;(r)</code>.</P>
<P><B>Throws:</B> nothing.</P>
</BLOCKQUOTE>
<P><EM>[The current implementation of <STRONG>make_shared</STRONG> can&nbsp;propagate
an exception&nbsp;thrown by the <STRONG>shared_ptr</STRONG> default
constructor, so it doesn't meet the stated requirements</EM><EM>. In a future
release, this default constructor will not throw.]</EM></P>
<h2><a name="FAQ">Frequently Asked Questions</a></h2>
<P><B>Q.</B> Can an object create a <STRONG>weak_ptr</STRONG> to itself in its
constructor?</P>
<P><b>A.</b> No. A <STRONG>weak_ptr</STRONG> can only be created from a <STRONG>shared_ptr</STRONG>,
and at object construction time no <STRONG>shared_ptr</STRONG> to the object
exists yet. Even if you could create a temporary <STRONG>shared_ptr</STRONG> to <STRONG>
this</STRONG>, it would go out of scope at the end of the constructor, and
all <STRONG>weak_ptr</STRONG> instances would instantly expire.</P>
<P>The solution is to make the constructor private, and supply a factory function
that returns a <STRONG>shared_ptr</STRONG>:<BR>
</P>
<pre>
class X
{
private:
X();
public:
static shared_ptr&lt;X&gt; create()
{
shared_ptr&lt;X&gt; px(new X);
// create weak pointers from px here
return px;
}
};
</pre>
<p><br></p>
<hr>
<p>Revised 29 August 2002<!--webbot bot="Timestamp" i-checksum="38439" endspan --></p>
<p>$Date$</p>
<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, 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>