diff --git a/shared_ptr.htm b/shared_ptr.htm index 87e61b4..c534dd7 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -45,9 +45,10 @@ shared_ptr<void> p2( new int(5) ); to "break cycles."

The class template is parameterized on T, the type of the object pointed 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.

+ 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 @@ -119,10 +120,13 @@ void bad() typedef see below element_type; shared_ptr(); // never throws + shared_ptr(std::nullptr_t); // never throws template<class Y> explicit shared_ptr(Y * p); template<class Y, class D> shared_ptr(Y * p, D d); template<class Y, class D, class A> shared_ptr(Y * p, D d, A a); + template<class D> shared_ptr(std::nullptr_t p, D d); + template<class D, class A> shared_ptr(std::nullptr_t p, D d, A a); ~shared_ptr(); // never throws @@ -152,6 +156,8 @@ void bad() template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r); + shared_ptr & operator=(std::nullptr_t); // never throws + void reset(); // never throws template<class Y> void reset(Y * p); @@ -163,19 +169,19 @@ void bad() T & operator*() const; // never throws; only valid when T is not an array type T * operator->() const; // never throws; only valid when T is not an array type - element_type & operator[]( std::ptrdiff_t i ) const; // never throws; only valid when T is an array type + element_type & operator[](std::ptrdiff_t i) const; // never throws; only valid when T is an array type element_type * get() const; // never throws bool unique() const; // never throws long use_count() const; // never throws - operator unspecified-bool-type() const; // never throws + explicit operator bool() const; // never throws void swap(shared_ptr & b); // never throws - template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const; // never throws - template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const; // never throws + template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const; // never throws + template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const; // never throws }; template<class T, class U> @@ -187,6 +193,18 @@ void bad() template<class T, class U> bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws + template<class T> + bool operator==(shared_ptr<T> const & p, std::nullptr_t); // never throws + + template<class T> + bool operator==(std::nullptr_t, shared_ptr<T> const & p); // never throws + + template<class T> + bool operator!=(shared_ptr<T> const & p, std::nullptr_t); // never throws + + template<class T> + bool operator!=(std::nullptr_t, shared_ptr<T> const & p); // never throws + template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws template<class T> typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p); // never throws @@ -217,7 +235,8 @@ void bad() and U when T is U[] or U[N].

default constructor

-
shared_ptr(); // never throws
+
shared_ptr(); // never throws
+shared_ptr(std::nullptr_t); // never throws

Effects: Constructs an empty shared_ptr.

Postconditions: use_count() == 0 && get() == 0.

@@ -260,7 +279,9 @@ void bad() not have a virtual destructor, or is void.]

constructors taking a deleter

template<class Y, class D> shared_ptr(Y * p, D d);
-template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);
+template<class Y, class D, class A> shared_ptr(Y * p, D d, A a); +template<class D> shared_ptr(std::nullptr_t p, D d); +template<class D, class A> shared_ptr(std::nullptr_t p, D d, A a);

Requirements: D must be CopyConstructible. The copy constructor and destructor @@ -273,8 +294,8 @@ template<class Y, class D, class A> shared_ptr(Y * p, D d, A a); otherwise, Y* must be convertible to T*.

Effects: Constructs a shared_ptr that owns the pointer - p and the deleter d. The second constructor allocates - memory using a copy of a.

+ p and the deleter d. The constructors taking an allocator a + allocate memory using a copy of a.

Postconditions: use_count() == 1 && get() == p.

Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.

@@ -350,8 +371,8 @@ template<class Y> shared_ptr(std::auto_ptr<Y> && r);

Requires: Y* should be convertible to T*.

Effects: - Equivalent to shared_ptr( r.release(), r.get_deleter() ) when D is not a reference type. - Otherwise, equivalent to shared_ptr( r.release(), del ), where del is a deleter + Equivalent to shared_ptr(r.release(), r.get_deleter()) when D is not a reference type. + Otherwise, equivalent to shared_ptr(r.release(), del), where del is a deleter that stores the reference rd returned from r.get_deleter() and del(p) calls rd(p).

Postconditions: use_count() == 1.

Throws: std::bad_alloc, or an implementation-defined @@ -401,7 +422,12 @@ template<class Y> shared_ptr & operator=(shared_ptr<Y> && template<class Y> shared_ptr & operator=(std::auto_ptr<Y> && r); template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r);

-

Effects: Equivalent to shared_ptr( std::move(r) ).swap(*this).

+

Effects: Equivalent to shared_ptr(std::move(r)).swap(*this).

+

Returns: *this.

+
+
shared_ptr & operator=(std::nullptr_t); // never throws
+
+

Effects: Equivalent to shared_ptr().swap(*this).

Returns: *this.

reset

@@ -438,11 +464,11 @@ template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y

Returns: the stored pointer.

Throws: nothing.

-
element_type & operator[]( std::ptrdiff_t i ) const; // never throws
+
element_type & operator[](std::ptrdiff_t i) const; // never throws

Requirements: T should be an array type. The stored pointer must not be 0. i >= 0. If T is U[N], i < N.

-

Returns: get()[ i ].

+

Returns: get()[i].

Throws: nothing.

get

@@ -471,15 +497,12 @@ template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y for debugging and testing purposes, not for production code.

conversions

-
operator unspecified-bool-type () const; // never throws
+
explicit operator bool() const; // never throws
-

Returns: an unspecified value that, when used in boolean contexts, is - equivalent to get() != 0.

+

Returns: 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, avoiding - many of the implicit conversion pitfalls.

+ used in boolean contexts, like if(p && p->valid()) {}.

[The conversion to bool is not merely syntactic sugar. It allows shared_ptrs to be declared in conditions when using dynamic_pointer_cast @@ -490,6 +513,13 @@ template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y

Effects: Exchanges the contents of the two smart pointers.

Throws: nothing.

+

swap

+
template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const; // never throws
+template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const; // never throws
+
+

Effects: See the description of operator<.

+

Throws: nothing.

+

Free Functions

comparison

template<class T, class U>
@@ -504,6 +534,22 @@ template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y
 			

Returns: a.get() != b.get().

Throws: nothing.

+
template<class T>
+  bool operator==(shared_ptr<T> const & p, std::nullptr_t); // never throws
+template<class T>
+  bool operator==(std::nullptr_t, shared_ptr<T> const & p); // never throws
+
+

Returns: p.get() == 0.

+

Throws: nothing.

+
+
template<class T>
+  bool operator!=(shared_ptr<T> const & p, std::nullptr_t); // never throws
+template<class T>
+  bool operator!=(std::nullptr_t, shared_ptr<T> const & p); // never throws
+
+

Returns: p.get() != 0.

+

Throws: nothing.

+
template<class T, class U>
   bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
@@ -743,7 +789,7 @@ p3.reset(new int(2)); // undefined, multiple writes

A. Automatic conversion is believed to be too error prone.

-

Q. Why does shared_ptr supply use_count()?

+

Q. Why does shared_ptr supply use_count()?

A. As an aid to writing test cases and debugging displays. One of the progenitors had use_count(), and it was useful in tracking down bugs in a @@ -783,7 +829,7 @@ int * p = a.release();


Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - Copyright 2002-2005, 2012 Peter Dimov. Distributed under the Boost Software License, + Copyright 2002-2005, 2012, 2013 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.