mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-08-01 13:44:37 +02:00
get_shared_ptr renamed to weak_ptr::lock.
[SVN r17307]
This commit is contained in:
@@ -24,8 +24,6 @@
|
|||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
template<class T> shared_ptr<T> get_shared_ptr(weak_ptr<T> const & r); // never throws
|
|
||||||
|
|
||||||
template<class T> class weak_ptr
|
template<class T> class weak_ptr
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -64,7 +62,7 @@ public:
|
|||||||
template<class Y>
|
template<class Y>
|
||||||
weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
|
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>
|
template<class Y>
|
||||||
@@ -77,7 +75,7 @@ public:
|
|||||||
template<class Y>
|
template<class Y>
|
||||||
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
|
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
|
||||||
{
|
{
|
||||||
px = boost::get_shared_ptr(r).get();
|
px = r.lock().get();
|
||||||
pn = r.pn;
|
pn = r.pn;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -92,9 +90,33 @@ public:
|
|||||||
|
|
||||||
#endif
|
#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
|
long use_count() const // never throws
|
||||||
@@ -107,6 +129,11 @@ public:
|
|||||||
return pn.use_count() == 0;
|
return pn.use_count() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset() // never throws in 1.30+
|
||||||
|
{
|
||||||
|
this_type().swap(*this);
|
||||||
|
}
|
||||||
|
|
||||||
void swap(this_type & other) // never throws
|
void swap(this_type & other) // never throws
|
||||||
{
|
{
|
||||||
std::swap(px, other.px);
|
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);
|
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
|
// deprecated, provided for backward compatibility
|
||||||
template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
|
template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
|
||||||
{
|
{
|
||||||
return boost::get_shared_ptr(r);
|
return r.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
@@ -390,8 +390,8 @@ q = p;
|
|||||||
many of the implicit conversion pitfalls.</P>
|
many of the implicit conversion pitfalls.</P>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<P><EM>[The conversion to bool is not merely syntactic sugar. It allows <STRONG>shared_ptr</STRONG>s
|
<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
|
to be declared in conditions when using <A href="#dynamic_pointer_cast">dynamic_pointer_cast</A> or
|
||||||
<STRONG>get_shared_ptr</STRONG>.]</EM></P>
|
<A href="weak_ptr.htm#lock">weak_ptr::lock</A>.]</EM></P>
|
||||||
<h3><a name="swap">swap</a></h3>
|
<h3><a name="swap">swap</a></h3>
|
||||||
<pre>void swap(shared_ptr & b); // never throws</pre>
|
<pre>void swap(shared_ptr & b); // never throws</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
@@ -413,7 +413,7 @@ public:
|
|||||||
|
|
||||||
virtual shared_ptr<X> getX()
|
virtual shared_ptr<X> getX()
|
||||||
{
|
{
|
||||||
shared_ptr<X> px = get_shared_ptr(weak_this);
|
shared_ptr<X> px = weak_this.lock();
|
||||||
return px;
|
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)
|
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.get() != 0);
|
||||||
BOOST_TEST(q->id() == 2);
|
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);
|
weak_ptr<X> wp2 = static_pointer_cast<X>(p5);
|
||||||
|
|
||||||
@@ -232,10 +232,10 @@ int main()
|
|||||||
// Scoped to not affect the subsequent use_count() tests.
|
// Scoped to not affect the subsequent use_count() tests.
|
||||||
{
|
{
|
||||||
shared_ptr<X> sp2(wp2);
|
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);
|
BOOST_TEST(wp3.use_count() == 1);
|
||||||
test_shared(wp2, wp3);
|
test_shared(wp2, wp3);
|
||||||
@@ -246,7 +246,7 @@ int main()
|
|||||||
test_shared(wp2, wp4);
|
test_shared(wp2, wp4);
|
||||||
|
|
||||||
wp1 = p2;
|
wp1 = p2;
|
||||||
test_is_zero(boost::get_shared_ptr(wp1));
|
test_is_zero(wp1.lock());
|
||||||
|
|
||||||
wp1 = p4;
|
wp1 = p4;
|
||||||
wp1 = wp3;
|
wp1 = wp3;
|
||||||
|
@@ -3094,7 +3094,7 @@ public:
|
|||||||
|
|
||||||
virtual boost::shared_ptr<X> getX()
|
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;
|
return px;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -1183,14 +1183,14 @@ void test()
|
|||||||
|
|
||||||
} // namespace n_comparison
|
} // namespace n_comparison
|
||||||
|
|
||||||
namespace n_get_shared_ptr
|
namespace n_lock
|
||||||
{
|
{
|
||||||
|
|
||||||
void test()
|
void test()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace n_get_shared_ptr
|
} // namespace n_lock
|
||||||
|
|
||||||
namespace n_map
|
namespace n_map
|
||||||
{
|
{
|
||||||
@@ -1272,7 +1272,7 @@ int main()
|
|||||||
n_use_count::test();
|
n_use_count::test();
|
||||||
n_swap::test();
|
n_swap::test();
|
||||||
n_comparison::test();
|
n_comparison::test();
|
||||||
n_get_shared_ptr::test();
|
n_lock::test();
|
||||||
|
|
||||||
n_map::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
|
<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>
|
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">
|
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">
|
the <STRONG>shared_ptr</STRONG> constructor</A> or the member function <STRONG><A href="#lock">
|
||||||
get_shared_ptr</A></STRONG>. When the last <b>shared_ptr</b> to the
|
lock</A></STRONG>. When the last <b>shared_ptr</b> to the object goes
|
||||||
object goes away and the object is deleted, the attempt to obtain a <STRONG>shared_ptr</STRONG>
|
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:
|
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>,
|
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
|
<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.
|
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
|
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
|
<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
|
very limited subset of operations since accessing its stored pointer is often
|
||||||
dangerous in multithreaded programs, and sometimes unsafe even within a single
|
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>
|
innocent piece of code:</P>
|
||||||
<pre>shared_ptr<int> p(new int(5));
|
<pre>shared_ptr<int> p(new int(5));
|
||||||
weak_ptr<int> q(p);
|
weak_ptr<int> q(p);
|
||||||
@@ -55,14 +56,16 @@ weak_ptr<int> q(p);
|
|||||||
|
|
||||||
// some time later
|
// 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
|
// use *r
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
<p>Now <STRONG>r</STRONG> holds a reference to the object that was pointed by <STRONG>q</STRONG>.
|
<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
|
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>
|
<h2><a name="Synopsis">Synopsis</a></h2>
|
||||||
<pre>namespace boost {
|
<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>(weak_ptr<Y> const & r);
|
||||||
template<class Y> weak_ptr & <A href="#assignment" >operator=</A>(shared_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;
|
long <A href="#use_count" >use_count</A>() const;
|
||||||
bool <A href="#expired" >expired</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);
|
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>
|
template<class T>
|
||||||
void <A href="#free-swap" >swap</A>(weak_ptr<T> & a, weak_ptr<T> & b);
|
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>
|
</pre>
|
||||||
<h2><a name="Members">Members</a></h2>
|
<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
|
<P><B>Notes:</B> The implementation is free to meet the effects (and the implied
|
||||||
guarantees) via different means, without creating a temporary.</P>
|
guarantees) via different means, without creating a temporary.</P>
|
||||||
</BLOCKQUOTE>
|
</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>
|
<h3><a name="use_count">use_count</a></h3>
|
||||||
<pre>long use_count() const;</pre>
|
<pre>long use_count() const;</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
@@ -165,6 +159,17 @@ template<class Y> weak_ptr & operator=(shared_ptr<Y> const &
|
|||||||
<p><b>Throws:</b> nothing.</p>
|
<p><b>Throws:</b> nothing.</p>
|
||||||
<P><B>Notes:</B> <code>expired()</code> may be faster than <code>use_count()</code>.</P>
|
<P><B>Notes:</B> <code>expired()</code> may be faster than <code>use_count()</code>.</P>
|
||||||
</blockquote>
|
</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>
|
<h3><a name="swap">swap</a></h3>
|
||||||
<pre>void swap(weak_ptr & b);</pre>
|
<pre>void swap(weak_ptr & b);</pre>
|
||||||
<blockquote>
|
<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
|
<P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to
|
||||||
generic programming.</P>
|
generic programming.</P>
|
||||||
</BLOCKQUOTE>
|
</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>
|
<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
|
<P><B>Q.</B> Can an object create a <STRONG>weak_ptr</STRONG> to itself in its
|
||||||
constructor?</P>
|
constructor?</P>
|
||||||
|
Reference in New Issue
Block a user