diff --git a/shared_ptr.htm b/shared_ptr.htm index 49649e2..fc9df88 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -31,12 +31,19 @@ work correctly with cyclic data structures. For example, if main() holds a shared_ptr to A, which directly or indirectly holds a shared_ptr back to A, A's use count will be 2. Destruction of the original shared_ptr - will leave A dangling with a use count of 1.
+ will leave A dangling with a use count of 1. Use weak_ptr + to "break cycles."The class template is parameterized on T, the type of the object pointed - to. T must meet the smart pointer - common requirements. T may be void, but in that case, - either an explicit delete function must be passed in, or the pointed-to object - must have a trivial destructor.
+ to. shared_ptr and most of its member functions place no + requirements on T; it is allowed to be an incomplete type, or + void. Member functions that do place additional requirements (constructors, + reset) are explicitly documented below. +shared_ptr<T> can be implicitly converted to shared_ptr<U> + whenever T* can be implicitly converted to U*. + In particular, shared_ptr<T> is implicitly convertible + to shared_ptr<T const>, to shared_ptr<U> + where U is an accessible base of T, and to + shared_ptr<void>.
namespace boost {
@@ -47,11 +54,12 @@
template<typename T> class shared_ptr {
public:
+
typedef T element_type;
shared_ptr ();
- explicit shared_ptr (T * p); // requires complete type
- template<typename D> shared_ptr(T * p, D d);
+ template<typename Y> explicit shared_ptr (Y * p);
+ template<typename Y, typename D> shared_ptr(Y * p, D d);
~shared_ptr(); // never throws
shared_ptr(shared_ptr const & r); // never throws
@@ -64,8 +72,8 @@
template<typename Y> shared_ptr & operator=(std::auto_ptr<Y> & r);
void reset ();
- void reset (T * p); // requires complete type
- template<typename D> void reset(T * p, D d);
+ template<typename Y> void reset (Y * p);
+ template<typename Y> template<typename D> void reset(Y * p, D d);
T & operator*() const; // never throws
T * operator->() const; // never throws
@@ -113,13 +121,12 @@
Throws: std::bad_alloc.
Exception safety: If an exception is thrown, the constructor has no
effect.
- Notes: T need not be a complete type. See the smart pointer
- common requirements.
- explicit shared_ptr(T * p);
+ template<typename Y> explicit shared_ptr(Y * p);
- Requirements: The expression delete p must be well-formed
- and must not invoke undefined behavior.
+
Requirements: p must be convertible to T *. Y
+ must be a complete type. The expression delete p must be
+ well-formed, must not invoke undefined behavior, and must not throw exceptions.
Effects: Constructs a shared_ptr, storing a copy of p.
Postconditions: use count is 1.
@@ -131,11 +138,12 @@
use count is 1 holds even if p is 0; invoking delete
on a pointer that has a value of 0 is harmless.
- template<typename D> shared_ptr(T * p, D d);
+ template<typename Y, typename D> shared_ptr(Y * p, D d);
- Requirements: The copy constructor and destructor of D must not
- throw. The expression d(p) must be well-formed, must not invoke
- undefined behavior, and must not throw exceptions.
+
Requirements: p must be convertible to T *. The copy
+ constructor and destructor of D must not throw. The expression d(p)
+ must be well-formed, must not invoke undefined behavior, and must not throw
+ exceptions.
Effects: Constructs a shared_ptr, storing a copy of p and d.
Postconditions: use count is 1.
@@ -180,10 +188,6 @@ template<typename Y> shared_ptr(shared_ptr<Y> const & r); // nev
Postconditions: use count for all remaining
copies is decreased by one.
Throws: nothing.
- Notes: T need not be a complete type. The guarantee that the
- destructor does not throw exceptions depends on the requirement that the
- deleted object's destructor does not throw exceptions. See the smart pointer
- common requirements.
assignment
shared_ptr & operator=(shared_ptr const & r); // never throws
@@ -207,12 +211,11 @@ q = p;
Effects: Equivalent to shared_ptr().swap(*this).
- void reset(T * p);
+ template<typename Y> void reset(Y * p);
Effects: Equivalent to shared_ptr(p).swap(*this).
- Notes: Note the implied requirement that T is a complete type.
- template<typename D> void reset(T * p, D d);
+ template<typename Y, typename D> void reset(Y * p, D d);
Effects: Equivalent to shared_ptr(p, d).swap(*this).
@@ -234,17 +237,13 @@ q = p;
Returns: the stored pointer.
Throws: nothing.
- Notes: T need not be a complete type. See the smart pointer
- common requirements.
unique
bool unique() const; // never throws
Returns: use_count() == 1.
Throws: nothing.
- Notes: unique() may be faster than use_count(). T
- need not be a complete type. See the smart pointer
- common requirements.
+ Notes: unique() may be faster than use_count().
use_count
long use_count() const; // never throws
@@ -253,9 +252,7 @@ q = p;
stored pointer.
Throws: nothing.
Notes: use_count() is not necessarily efficient. Use only
- for debugging and testing purposes, not for production code. T need not
- be a complete type. See the smart pointer
- common requirements.
+ for debugging and testing purposes, not for production code.
conversions
operator implementation-defined-type () const; // never throws
@@ -264,17 +261,15 @@ q = p;
contexts, is equivalent to get() != 0.
Throws: nothing.
Notes: This conversion operator allows shared_ptr objects to be
- used in boolean contexts, like if (p && p->valid()) {}. The
- actual target type is typically a pointer to a member function, avloiding many
- of the implicit conversion pitfalls.
+ used in boolean contexts, like if (p && p->valid()) {}.
+ The actual target type is typically a pointer to a member function, avloiding
+ many of the implicit conversion pitfalls.
swap
void swap(shared_ptr & b); // never throws
Effects: Exchanges the contents of the two smart pointers.
Throws: nothing.
- Notes: T need not be a complete type. See the smart pointer
- common requirements.
Free Functions
comparison
@@ -283,27 +278,22 @@ q = p;
Returns: a.get() == b.get().
Throws: nothing.
- Notes: T need not be a complete type. See the smart pointer
- common requirements.
template<typename T, typename U>
bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
Returns: a.get() != b.get().
Throws: nothing.
- Notes: T need not be a complete type. See the smart pointer
- common requirements.
template<typename T>
bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b); // never throws
- Returns: an implementation-defined value such that operator<
- is a strict weak ordering as described in section 25.3 [lib.alg.sorting]
+
Returns: an implementation-defined value such that operator< is
+ a strict weak ordering as described in section 25.3 [lib.alg.sorting]
of the C++ standard.
Throws: nothing.
Notes: Allows shared_ptr objects to be used as keys in
- associative containers. T need not be a complete type. See the smart
- pointer common requirements.
+ associative containers.
swap
template<typename T>
@@ -337,14 +327,13 @@ q = p;
Returns:
dynamic_cast<T*>(r.get()) returns a nonzero
- value, a shared_ptr<T> object that stores a copy of
- it and shares ownership with r;
+ When dynamic_cast<T*>(r.get()) returns a nonzero value, a
+ shared_ptr<T> object that stores a copy of it and shares
+ ownership with r;
Throws: std::bad_alloc.
-Exception safety: If an exception is thrown, the function has no - effect.
+Exception safety: If an exception is thrown, the function has no effect.
Notes: the seemingly equivalent expression
shared_ptr<T>(dynamic_cast<T*>(r.get()))
will eventually result in undefined behavior, attempting to delete the same @@ -456,8 +445,8 @@ int * p = a.release(); implementation or a linked list implementation, or some other specific implementation. This is not the intent.
Revised - 14 February 2002
+Revised + 04 May 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