diff --git a/enable_shared_from_this.html b/enable_shared_from_this.html index 028cf57..f04f312 100644 --- a/enable_shared_from_this.html +++ b/enable_shared_from_this.html @@ -2,21 +2,25 @@ enable_shared_from_this - + -

boost.png (6897 bytes)enable_shared_from_this

+

boost.png (6897 bytes)enable_shared_from_this

Purpose

- The header <boost/enable_shared_from_this.hpp> defines - the class template enable_shared_from_this. It is used as a - base class that allows a shared_ptr to the current - object to be obtained from within a member function. + The header <boost/enable_shared_from_this.hpp> defines + the class template enable_shared_from_this. It is used as a + base class that allows a shared_ptr or + a weak_ptr to the current object to be obtained + from within a member function. +

+

enable_shared_from_this<T> defines two member functions + called shared_from_this that return a shared_ptr<T> + and shared_ptr<T const>, depending on constness, to this. + It also defines two member functions called weak_from_this that return + a corresponding weak_ptr.

-

enable_shared_from_this<T> defines two member functions - called shared_from_this that return a shared_ptr<T> - and shared_ptr<T const>, depending on constness, to this.

Example

 #include <boost/enable_shared_from_this.hpp>
@@ -41,7 +45,7 @@ int main()
     assert(!(p < q || q < p)); // p and q must share ownership
 }
 
-

Synopsis

+

Synopsis

 namespace boost
 {
@@ -52,34 +56,55 @@ public:
 
     shared_ptr<T> shared_from_this();
     shared_ptr<T const> shared_from_this() const;
+
+    weak_ptr<T> weak_from_this() noexcept;
+    weak_ptr<T const> weak_from_this() const noexcept;
 }
 
 }
 
-

template<class T> shared_ptr<T> - enable_shared_from_this<T>::shared_from_this();

-

template<class T> shared_ptr<T const> - enable_shared_from_this<T>::shared_from_this() const;

+

template<class T> shared_ptr<T> + enable_shared_from_this<T>::shared_from_this();

+

template<class T> shared_ptr<T const> + enable_shared_from_this<T>::shared_from_this() const;

- Requires: enable_shared_from_this<T> must be an - accessible base class of T. *this must be a subobject - of an instance t of type T . There must exist - at least one shared_ptr instance p that owns - t. + Requires: enable_shared_from_this<T> must be an + accessible base class of T. *this must be a subobject + of an instance t of type T.

- Returns: A shared_ptr<T> instance r that shares - ownership with p. + Returns: If a shared_ptr instance p that owns + t exists, a shared_ptr<T> instance r that shares + ownership with p.

- Postconditions: r.get() == this. + Postconditions: r.get() == this. +

+

+ Throws: bad_weak_ptr when no shared_ptr owns *this.

-

$Date$

+

template<class T> weak_ptr<T> + enable_shared_from_this<T>::weak_from_this() noexcept;

+

template<class T> weak_ptr<T const> + enable_shared_from_this<T>::weak_from_this() const noexcept;

+
+

+ Requires: enable_shared_from_this<T> must be an + accessible base class of T. *this must be a subobject + of an instance t of type T. +

+

+ Returns: If a shared_ptr instance p that owns + t exists or has existed in the past, a weak_ptr<T> instance + r that shares ownership with p. Otherwise, an empty weak_ptr. +

+
+

- Copyright © 2002, 2003 by Peter Dimov. Distributed under the Boost Software License, Version - 1.0. See accompanying file LICENSE_1_0.txt or - copy at http://www.boost.org/LICENSE_1_0.txt.

+ Copyright © 2002, 2003, 2015 by Peter Dimov. Distributed under the Boost Software License, Version + 1.0. See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt.

diff --git a/include/boost/smart_ptr/enable_shared_from_this.hpp b/include/boost/smart_ptr/enable_shared_from_this.hpp index 3230f02..4e3f243 100644 --- a/include/boost/smart_ptr/enable_shared_from_this.hpp +++ b/include/boost/smart_ptr/enable_shared_from_this.hpp @@ -58,6 +58,16 @@ public: return p; } + weak_ptr weak_from_this() BOOST_NOEXCEPT + { + return weak_this_; + } + + weak_ptr weak_from_this() const BOOST_NOEXCEPT + { + return weak_this_; + } + public: // actually private, but avoids compiler template friendship issues // Note: invoked automatically by shared_ptr; do not call diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index a848d4f..8f73f70 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -175,5 +175,8 @@ import testing ; [ run weak_from_raw_test4.cpp ] [ compile sp_explicit_inst_test.cpp ] + + [ run weak_from_this_test.cpp ] + [ run weak_from_this_test2.cpp ] ; } diff --git a/test/weak_from_raw_test4.cpp b/test/weak_from_raw_test4.cpp index 646b84e..2408f00 100644 --- a/test/weak_from_raw_test4.cpp +++ b/test/weak_from_raw_test4.cpp @@ -1,7 +1,7 @@ // // weak_from_raw_test4.cpp // -// As weak_from_raw_test2.cpp, but uses weak_from_this +// As weak_from_raw_test2.cpp, but uses weak_from_raw // in the constructor // // Copyright (c) 2014, 2015 Peter Dimov diff --git a/test/weak_from_this_test.cpp b/test/weak_from_this_test.cpp new file mode 100644 index 0000000..1a874e1 --- /dev/null +++ b/test/weak_from_this_test.cpp @@ -0,0 +1,52 @@ +#include + +// +// weak_from_this_test.cpp +// +// Copyright (c) 2002, 2003, 2015 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + + +#include +#include +#include +#include + +class V: public boost::enable_shared_from_this +{ +}; + +void test() +{ + boost::shared_ptr p( new V ); + + boost::weak_ptr q = p; + BOOST_TEST( !q.expired() ); + + boost::weak_ptr q2 = p->weak_from_this(); + BOOST_TEST( !q2.expired() ); + BOOST_TEST( !(q < q2) && !(q2 < q) ); + + V v2( *p ); + + boost::weak_ptr q3 = v2.weak_from_this(); + BOOST_TEST( q3.expired() ); + + *p = V(); + + boost::weak_ptr q4 = p->shared_from_this(); + BOOST_TEST( !q4.expired() ); + BOOST_TEST( !(q < q4) && !(q4 < q) ); + BOOST_TEST( !(q2 < q4) && !(q4 < q2) ); +} + +int main() +{ + test(); + return boost::report_errors(); +} diff --git a/test/weak_from_this_test2.cpp b/test/weak_from_this_test2.cpp new file mode 100644 index 0000000..05f3df2 --- /dev/null +++ b/test/weak_from_this_test2.cpp @@ -0,0 +1,60 @@ +// +// weak_from_this_test2.cpp +// +// Tests weak_from_this in a destructor +// +// Copyright (c) 2014, 2015 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include +#include +#include + +class X: public boost::enable_shared_from_this< X > +{ +private: + + boost::weak_ptr px_; + +public: + + X() + { + boost::weak_ptr p1 = weak_from_this(); + BOOST_TEST( p1._empty() ); + BOOST_TEST( p1.expired() ); + } + + void check() + { + boost::weak_ptr p2 = weak_from_this(); + BOOST_TEST( !p2.expired() ); + + BOOST_TEST( p2.lock().get() == this ); + + px_ = p2; + } + + ~X() + { + boost::weak_ptr p3 = weak_from_this(); + BOOST_TEST( p3.expired() ); + + BOOST_TEST( !(px_ < p3) && !(p3 < px_) ); + } +}; + +int main() +{ + { + boost::shared_ptr< X > px( new X ); + px->check(); + } + + return boost::report_errors(); +}