mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-07-31 21:24:40 +02:00
get_shared_ptr renamed to weak_ptr::lock.
[SVN r17307]
This commit is contained in:
@@ -24,8 +24,6 @@
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> shared_ptr<T> get_shared_ptr(weak_ptr<T> const & r); // never throws
|
||||
|
||||
template<class T> class weak_ptr
|
||||
{
|
||||
private:
|
||||
@@ -64,7 +62,7 @@ public:
|
||||
template<class Y>
|
||||
weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
|
||||
{
|
||||
px = boost::get_shared_ptr(r).get();
|
||||
px = r.lock().get();
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
@@ -77,7 +75,7 @@ public:
|
||||
template<class Y>
|
||||
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
|
||||
{
|
||||
px = boost::get_shared_ptr(r).get();
|
||||
px = r.lock().get();
|
||||
pn = r.pn;
|
||||
return *this;
|
||||
}
|
||||
@@ -92,9 +90,33 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
void reset() // never throws in 1.30+
|
||||
shared_ptr<T> lock() const // never throws
|
||||
{
|
||||
this_type().swap(*this);
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
|
||||
// optimization: avoid throw overhead
|
||||
if(expired())
|
||||
{
|
||||
return shared_ptr<element_type>();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return shared_ptr<element_type>(*this);
|
||||
}
|
||||
catch(bad_weak_ptr const &)
|
||||
{
|
||||
// Q: how can we get here?
|
||||
// A: another thread may have invalidated r after the use_count test above.
|
||||
return shared_ptr<element_type>();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// optimization: avoid try/catch overhead when single threaded
|
||||
return expired()? shared_ptr<element_type>(): shared_ptr<element_type>(*this);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
@@ -107,6 +129,11 @@ public:
|
||||
return pn.use_count() == 0;
|
||||
}
|
||||
|
||||
void reset() // never throws in 1.30+
|
||||
{
|
||||
this_type().swap(*this);
|
||||
}
|
||||
|
||||
void swap(this_type & other) // never throws
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
@@ -151,39 +178,10 @@ template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
template<class T> shared_ptr<T> get_shared_ptr(weak_ptr<T> const & r) // never throws
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
|
||||
// optimization: avoid throw overhead
|
||||
if(r.use_count() == 0)
|
||||
{
|
||||
return shared_ptr<T>();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return shared_ptr<T>(r);
|
||||
}
|
||||
catch(bad_weak_ptr const &)
|
||||
{
|
||||
// Q: how can we get here?
|
||||
// A: another thread may have invalidated r after the use_count test above.
|
||||
return shared_ptr<T>();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// optimization: avoid try/catch overhead when single threaded
|
||||
return r.use_count() == 0? shared_ptr<T>(): shared_ptr<T>(r);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// deprecated, provided for backward compatibility
|
||||
template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
|
||||
{
|
||||
return boost::get_shared_ptr(r);
|
||||
return r.lock();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
@@ -390,8 +390,8 @@ q = p;
|
||||
many of the implicit conversion pitfalls.</P>
|
||||
</blockquote>
|
||||
<P><EM>[The conversion to bool is not merely syntactic sugar. It allows <STRONG>shared_ptr</STRONG>s
|
||||
to be declared in conditions when using <STRONG>dynamic_pointer_cast </STRONG>or
|
||||
<STRONG>get_shared_ptr</STRONG>.]</EM></P>
|
||||
to be declared in conditions when using <A href="#dynamic_pointer_cast">dynamic_pointer_cast</A> or
|
||||
<A href="weak_ptr.htm#lock">weak_ptr::lock</A>.]</EM></P>
|
||||
<h3><a name="swap">swap</a></h3>
|
||||
<pre>void swap(shared_ptr & b); // never throws</pre>
|
||||
<blockquote>
|
||||
|
@@ -413,7 +413,7 @@ public:
|
||||
|
||||
virtual shared_ptr<X> getX()
|
||||
{
|
||||
shared_ptr<X> px = get_shared_ptr(weak_this);
|
||||
shared_ptr<X> px = weak_this.lock();
|
||||
return px;
|
||||
}
|
||||
};
|
||||
|
@@ -94,7 +94,7 @@ template<class T> void test_is_Y(boost::shared_ptr<T> const & p)
|
||||
|
||||
template<class T> void test_is_Y(boost::weak_ptr<T> const & p)
|
||||
{
|
||||
boost::shared_ptr<T> q = boost::get_shared_ptr(p);
|
||||
boost::shared_ptr<T> q = p.lock();
|
||||
BOOST_TEST(q.get() != 0);
|
||||
BOOST_TEST(q->id() == 2);
|
||||
}
|
||||
@@ -221,7 +221,7 @@ int main()
|
||||
{
|
||||
}
|
||||
|
||||
test_is_zero(boost::get_shared_ptr(wp1));
|
||||
test_is_zero(wp1.lock());
|
||||
|
||||
weak_ptr<X> wp2 = static_pointer_cast<X>(p5);
|
||||
|
||||
@@ -232,10 +232,10 @@ int main()
|
||||
// Scoped to not affect the subsequent use_count() tests.
|
||||
{
|
||||
shared_ptr<X> sp2(wp2);
|
||||
test_is_nonzero(boost::get_shared_ptr(wp2));
|
||||
test_is_nonzero(wp2.lock());
|
||||
}
|
||||
|
||||
weak_ptr<Y> wp3 = dynamic_pointer_cast<Y>(boost::get_shared_ptr(wp2));
|
||||
weak_ptr<Y> wp3 = dynamic_pointer_cast<Y>(wp2.lock());
|
||||
|
||||
BOOST_TEST(wp3.use_count() == 1);
|
||||
test_shared(wp2, wp3);
|
||||
@@ -246,7 +246,7 @@ int main()
|
||||
test_shared(wp2, wp4);
|
||||
|
||||
wp1 = p2;
|
||||
test_is_zero(boost::get_shared_ptr(wp1));
|
||||
test_is_zero(wp1.lock());
|
||||
|
||||
wp1 = p4;
|
||||
wp1 = wp3;
|
||||
|
@@ -3094,7 +3094,7 @@ public:
|
||||
|
||||
virtual boost::shared_ptr<X> getX()
|
||||
{
|
||||
boost::shared_ptr<X> px = boost::get_shared_ptr(weak_this);
|
||||
boost::shared_ptr<X> px = weak_this.lock();
|
||||
return px;
|
||||
}
|
||||
};
|
||||
|
@@ -1183,14 +1183,14 @@ void test()
|
||||
|
||||
} // namespace n_comparison
|
||||
|
||||
namespace n_get_shared_ptr
|
||||
namespace n_lock
|
||||
{
|
||||
|
||||
void test()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace n_get_shared_ptr
|
||||
} // namespace n_lock
|
||||
|
||||
namespace n_map
|
||||
{
|
||||
@@ -1272,7 +1272,7 @@ int main()
|
||||
n_use_count::test();
|
||||
n_swap::test();
|
||||
n_comparison::test();
|
||||
n_get_shared_ptr::test();
|
||||
n_lock::test();
|
||||
|
||||
n_map::test();
|
||||
|
||||
|
48
weak_ptr.htm
48
weak_ptr.htm
@@ -17,12 +17,12 @@
|
||||
<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="#get_shared_ptr">
|
||||
get_shared_ptr</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>
|
||||
the <STRONG>shared_ptr</STRONG> constructor</A> or the member function <STRONG><A href="#lock">
|
||||
lock</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::bad_weak_ptr</STRONG>,
|
||||
and <STRONG>get_shared_ptr</STRONG> will return an <EM>empty</EM> <STRONG>shared_ptr</STRONG>.</p>
|
||||
and <STRONG>weak_ptr::lock</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
|
||||
@@ -33,7 +33,8 @@
|
||||
<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
|
||||
thread (that is, it may invoke undefined behavior.) Pretend for a moment that <b>weak_ptr</b>
|
||||
has a <b>get</b> member function that returns a raw pointer, and consider this
|
||||
innocent piece of code:</P>
|
||||
<pre>shared_ptr<int> p(new int(5));
|
||||
weak_ptr<int> q(p);
|
||||
@@ -55,14 +56,16 @@ weak_ptr<int> q(p);
|
||||
|
||||
// some time later
|
||||
|
||||
if(shared_ptr<int> r = <A href="#get_shared_ptr" >get_shared_ptr</A>(q))
|
||||
if(shared_ptr<int> r = q.<A href="#lock" >lock</A>())
|
||||
{
|
||||
// use *r
|
||||
}
|
||||
</pre>
|
||||
<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>
|
||||
stay alive until <STRONG>r</STRONG> goes out of scope or is reset. By obtaining
|
||||
a <STRONG>shared_ptr</STRONG> to the object, we have effectively locked it
|
||||
against destruction.</p>
|
||||
<h2><a name="Synopsis">Synopsis</a></h2>
|
||||
<pre>namespace boost {
|
||||
|
||||
@@ -83,11 +86,11 @@ if(shared_ptr<int> r = <A href="#get_shared_ptr" >get_shared_ptr</A>(q))
|
||||
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);
|
||||
|
||||
void <A href="#reset" >reset</A>();
|
||||
|
||||
long <A href="#use_count" >use_count</A>() const;
|
||||
bool <A href="#expired" >expired</A>() const;
|
||||
shared_ptr<T> <A href="#lock" >lock</A>() const;
|
||||
|
||||
void <A href="#reset" >reset</A>();
|
||||
void <A href="#swap" >swap</A>(weak_ptr<T> & b);
|
||||
};
|
||||
|
||||
@@ -96,10 +99,6 @@ if(shared_ptr<int> r = <A href="#get_shared_ptr" >get_shared_ptr</A>(q))
|
||||
|
||||
template<class T>
|
||||
void <A href="#free-swap" >swap</A>(weak_ptr<T> & a, weak_ptr<T> & b);
|
||||
|
||||
template<class T>
|
||||
shared_ptr<T> <A href="#get_shared_ptr" >get_shared_ptr</A>(weak_ptr<T> const & r);
|
||||
|
||||
}
|
||||
</pre>
|
||||
<h2><a name="Members">Members</a></h2>
|
||||
@@ -143,11 +142,6 @@ template<class Y> weak_ptr & operator=(shared_ptr<Y> const &
|
||||
<P><B>Notes:</B> The implementation is free to meet the effects (and the implied
|
||||
guarantees) via different means, without creating a temporary.</P>
|
||||
</BLOCKQUOTE>
|
||||
<h3><a name="reset">reset</a></h3>
|
||||
<pre>void reset();</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Equivalent to <code>weak_ptr().swap(*this)</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<h3><a name="use_count">use_count</a></h3>
|
||||
<pre>long use_count() const;</pre>
|
||||
<blockquote>
|
||||
@@ -165,6 +159,17 @@ template<class Y> weak_ptr & operator=(shared_ptr<Y> const &
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
<P><B>Notes:</B> <code>expired()</code> may be faster than <code>use_count()</code>.</P>
|
||||
</blockquote>
|
||||
<h3><a name="lock">lock</a></h3>
|
||||
<pre>shared_ptr<T> lock() const;</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Returns:</B> <code>expired()? shared_ptr<T>(): shared_ptr<T>(*this)</code>.</P>
|
||||
<P><B>Throws:</B> nothing.</P>
|
||||
</BLOCKQUOTE>
|
||||
<h3><a name="reset">reset</a></h3>
|
||||
<pre>void reset();</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Equivalent to <code>weak_ptr().swap(*this)</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<h3><a name="swap">swap</a></h3>
|
||||
<pre>void swap(weak_ptr & b);</pre>
|
||||
<blockquote>
|
||||
@@ -198,13 +203,6 @@ template<class Y> weak_ptr & operator=(shared_ptr<Y> const &
|
||||
<P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to
|
||||
generic programming.</P>
|
||||
</BLOCKQUOTE>
|
||||
<h3><a name="get_shared_ptr">get_shared_ptr</a></h3>
|
||||
<pre>template<class T>
|
||||
shared_ptr<T> get_shared_ptr(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>
|
||||
<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>
|
||||
|
Reference in New Issue
Block a user