diff --git a/weak_ptr.htm b/weak_ptr.htm index 6c1d5dd..72104fb 100644 --- a/weak_ptr.htm +++ b/weak_ptr.htm @@ -18,6 +18,40 @@
The class template is parameterized on T, the type of the object pointed to. T must meet the smart pointer common requirements.
+Compared to shared_ptr, weak_ptr provides + a very limited subset of operations since accessing its stored pointer is + unsafe in multithreaded programs (that is, it may invoke undefined + behavior.) Consider, for example, this innocent piece of code:
++shared_ptr<int> p(new int(5)); +weak_ptr<int> q(p); + +// some time later + +if(int * r = q.get()) +{ + // use *r +} ++
Imagine that after the if, but immediately before r
+ is used, another thread executes the statement p.reset()
. Now r
+ is a dangling pointer.
The solution to this problem is to create a temporary shared_ptr + from q:
++shared_ptr<int> p(new int(5)); +weak_ptr<int> q(p); + +// some time later + +if(shared_ptr<int> r = make_shared(q)) +{ + // use *r +} ++
Now r holds a reference to the object that was pointed by q.
+ Even if p.reset()
is executed in another thread, the object will
+ stay alive until r goes out of scope (or is reset.)
namespace boost { @@ -58,15 +92,6 @@ template<typename T> shared_ptr<T> make_shared(weak_ptr<T> const & r); // never throws - template<typename T, typename U> - weak_ptr<T> shared_static_cast(weak_ptr<U> const & r); // never throws - template<typename T, typename U> - weak_ptr<T> shared_dynamic_cast(weak_ptr<U> const & r); - template<typename T, typename U> - weak_ptr<T> shared_polymorphic_cast(weak_ptr<U> const & r); - template<typename T, typename U> - weak_ptr<T> shared_polymorphic_downcast(weak_ptr<U> const & r); // never throws - }
Returns: r.expired()? shared_ptr<T>(): shared_ptr<T>(r)
.
Throws: nothing.
-template<typename T, typename U> - weak_ptr<T> shared_static_cast(weak_ptr<U> const & r); // never throws-
--Requires: The expression
-static_cast<T*>(r.get())
- must be well-formed.Returns: A weak_ptr<T> object that stores a copy - of
-static_cast<T*>(r.get())
and shares ownership with r.Throws: nothing.
-
template<typename T, typename U> - weak_ptr<T> shared_dynamic_cast(weak_ptr<U> const & r);-
--Requires: The expression
-dynamic_cast<T*>(r.get())
- must be well-formed and its behavior defined.Returns:
--
-- - When
dynamic_cast<T*>(r.get())
returns a nonzero - value, a weak_ptr<T> object that stores a copy of - it and shares ownership with r; -- - Otherwise, a default-constructed weak_ptr<T> object.
Throws: std::bad_alloc.
-Exception safety: If an exception is thrown, the function has no effect.
-
template<typename T, typename U> - weak_ptr<T> shared_polymorphic_cast(weak_ptr<U> const & r);-
--Requires: The expression
-- polymorphic_cast<T*>(r.get())
must be well-formed and - its behavior defined.Returns: A weak_ptr<T> object that stores a copy - of
-polymorphic_cast<T*>(r.get())
- and shares ownership with r.Throws: std::bad_cast when the pointer cannot be - converted.
-Exception safety: If an exception is thrown, the function has no effect.
-
template<typename T, typename U> - weak_ptr<T> shared_polymorphic_downcast(weak_ptr<U> const & r); // never throws-
-Requires: The expression
-- polymorphic_downcast<T*>(r.get())
must be well-formed - and its behavior defined.Returns: A weak_ptr<T> object that stores a copy - of
-polymorphic_downcast<T*>(r.get())
- and shares ownership with r.Throws: nothing.
-
Revised - 8 March 2002
+Revised 12 March 2002
Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Copyright 2002 Peter Dimov. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in