forked from boostorg/smart_ptr
weak_ptr documentation updated; still a work in progress.
[SVN r16748]
This commit is contained in:
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>
|
||||
|
251
weak_ptr.htm
251
weak_ptr.htm
@ -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 "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">
|
||||
<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, 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::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 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 <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<int> 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<int> p(new int(5));
|
||||
weak_ptr<int> 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<int> p(new int(5));
|
||||
<pre>shared_ptr<int> p(new int(5));
|
||||
weak_ptr<int> q(p);
|
||||
|
||||
// some time later
|
||||
|
||||
if(shared_ptr<int> r = <a href="#make_shared">make_shared</a>(q))
|
||||
if(shared_ptr<int> r = <A href="#make_shared" >make_shared</A>(q))
|
||||
{
|
||||
// use *r
|
||||
}
|
||||
@ -58,45 +64,53 @@ if(shared_ptr<int> 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<weak_ptr, ...> - 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<class T> 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<class Y> <a href="#constructors">weak_ptr</a>(shared_ptr<Y> const & 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 & r); // never throws
|
||||
template<class Y> <a href="#constructors">weak_ptr</a>(weak_ptr<Y> const & r); // never throws
|
||||
template<class Y> <A href="#constructors" >weak_ptr</A>(shared_ptr<Y> const & r);
|
||||
<A href="#constructors" >weak_ptr</A>(weak_ptr const & r);
|
||||
template<class Y> <A href="#constructors" >weak_ptr</A>(weak_ptr<Y> const & r);
|
||||
|
||||
weak_ptr & <a href="#assignment">operator=</a>(weak_ptr const & r); // never throws
|
||||
template<class Y> weak_ptr & <a href="#assignment">operator=</a>(weak_ptr<Y> const & r); // never throws
|
||||
template<class Y> weak_ptr & <a href="#assignment">operator=</a>(shared_ptr<Y> const & 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 & <A href="#assignment" >operator=</A>(weak_ptr const & r);
|
||||
template<class Y> weak_ptr & <A href="#assignment" >operator=</A>(weak_ptr<Y> const & r);
|
||||
template<class Y> weak_ptr & <A href="#assignment" >operator=</A>(shared_ptr<Y> const & 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<T> & 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<T> & b);
|
||||
};
|
||||
|
||||
template<class T, class U>
|
||||
bool <a href="#comparison">operator==</a>(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws
|
||||
template<class T, class U>
|
||||
bool <a href="#comparison">operator!=</a>(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws
|
||||
template<class T>
|
||||
bool <a href="#comparison">operator<</a>(weak_ptr<T> const & a, weak_ptr<T> const & b); // never throws
|
||||
|
||||
template<class T> void <a href="#free-swap">swap</a>(weak_ptr<T> & a, weak_ptr<T> & b); // never throws
|
||||
bool <A href="#comparison" >operator<</A>(weak_ptr<T> const & a, weak_ptr<U> const & b);
|
||||
|
||||
template<class T>
|
||||
shared_ptr<T> <a href="#make_shared">make_shared</a>(weak_ptr<T> const & r); // never throws
|
||||
void <A href="#free-swap" >swap</A>(weak_ptr<T> & a, weak_ptr<T> & b);
|
||||
|
||||
template<class T>
|
||||
shared_ptr<T> <A href="#make_shared" >make_shared</A>(weak_ptr<T> const & r);
|
||||
|
||||
}
|
||||
</pre>
|
||||
@ -106,49 +120,34 @@ if(shared_ptr<int> 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<class Y> weak_ptr</A>(shared_ptr<Y> const & 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<class Y> weak_ptr</A>(shared_ptr<Y> const & r);
|
||||
weak_ptr(weak_ptr const & r);
|
||||
template<class Y> weak_ptr(weak_ptr<Y> const & 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 & r); // never throws
|
||||
template<class Y> weak_ptr(weak_ptr<Y> const & 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 & <a href="#assignment">operator=</a>(weak_ptr const & r); // never throws
|
||||
template<class Y> weak_ptr & <a href="#assignment">operator=</a>(weak_ptr<Y> const & r); // never throws
|
||||
template<class Y> weak_ptr & <a href="#assignment">operator=</a>(shared_ptr<Y> const & r); // never throws</pre>
|
||||
<pre>weak_ptr & <A href="#assignment" >operator=</A>(weak_ptr const & r);
|
||||
template<class Y> weak_ptr & <A href="#assignment" >operator=</A>(weak_ptr<Y> const & r);
|
||||
template<class Y> weak_ptr & <A href="#assignment" >operator=</A>(shared_ptr<Y> const & 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<class Y> weak_ptr & <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 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> 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 & b); // never throws</pre>
|
||||
<pre>void swap(weak_ptr & 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<class T, class U>
|
||||
bool operator==(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws
|
||||
template<class T, class U>
|
||||
bool operator!=(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws</pre>
|
||||
bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & 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<class T>
|
||||
bool operator<(weak_ptr<T> const & a, weak_ptr<T> const & b); // never throws</pre>
|
||||
<blockquote>
|
||||
<p><b>Returns:</b> an implementation-defined value such that <b>operator<</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<</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<</STRONG>, <code>!(a
|
||||
< b) && !(b < 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<class T>
|
||||
void swap(weak_ptr<T> & a, weak_ptr<T> & b) // never throws</pre>
|
||||
void swap(weak_ptr<T> & a, weak_ptr<T> & 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<class T, class U>
|
||||
</BLOCKQUOTE>
|
||||
<h3><a name="make_shared">make_shared</a></h3>
|
||||
<pre>template<class T>
|
||||
shared_ptr<T> make_shared(weak_ptr<T> & const r) // never throws</pre>
|
||||
shared_ptr<T> make_shared(weak_ptr<T> & const r)</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Returns:</B> <code>r.expired()? shared_ptr<T>(): shared_ptr<T>(r)</code>.</P>
|
||||
<P><B>Throws:</B> nothing.</P>
|
||||
</BLOCKQUOTE>
|
||||
<P><EM>[The current implementation of <STRONG>make_shared</STRONG> can propagate
|
||||
an exception 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<X> create()
|
||||
{
|
||||
shared_ptr<X> 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>
|
||||
|
Reference in New Issue
Block a user