From 540149f01986e70d79ffad5ad92148fda8953254 Mon Sep 17 00:00:00 2001
From: Glen Fernandes The February 2002 change to the Boost smart pointers introduced a number of
- changes. Since the previous version of the smart pointers was in use for a long
- time, it's useful to have a detailed list of what changed from a library user's
- point of view. Note that for compilers that don't support member templates well enough, a
- separate implementation is used that lacks many of the new features and is more
- like the old version. Revised 1 February 2002 Copyright 2002 Darin Adler. 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. The February 2002 change to the Boost smart pointers introduced a number of
+ changes. Since the previous version of the smart pointers was in use for a long
+ time, it's useful to have a detailed list of what changed from a library user's
+ point of view. Note that for compilers that don't support member templates well enough, a
+ separate implementation is used that lacks many of the new features and is more
+ like the old version. $Date$ Copyright 2002 Darin Adler. 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.
- 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.
- 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.
+ 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.
+ 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.
- 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.
-
- Returns: A shared_ptr<T> instance r that shares
- ownership with p.
-
- Postconditions: r.get() == this.
-
-
+ 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.
+
+ Returns: A shared_ptr<T> instance r that shares
+ ownership with p.
+
+ Postconditions: r.get() == this.
+ $Date$
+ 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.
- Introduction The The class template is parameterized on The main reasons to use As a general rule, if it isn't obvious whether
+ Introduction The The class template is parameterized on The main reasons to use As a general rule, if it isn't obvious whether Provides the type of the template parameter Postconditions: Throws: nothing. Effects: Postconditions: Provides the type of the template parameter Postconditions: Throws: nothing. Effects: Postconditions: Effects: Postconditions: Effects: Effects: Postconditions: Effects: Effects: Equivalent to Returns: Effects: Equivalent to Effects: Equivalent to Effects: Equivalent to Requirements: Returns: Throws: nothing. Requirements: Returns: Throws: nothing. Returns: the stored pointer. Throws: nothing. Returns: the stored pointer. Throws: nothing. Postconditions: Notes: The returned pointer has an elevated reference count. This
- allows conversion of an Caution: Using Returns: an unspecified value that, when used in boolean contexts, is
- equivalent to Throws: nothing. Notes: This conversion operator allows Effects: Exchanges the contents of the two smart pointers. Throws: nothing. Effects: Equivalent to Returns: Effects: Equivalent to Effects: Equivalent to Effects: Equivalent to Requirements: Returns: Throws: nothing. Requirements: Returns: Throws: nothing. Returns: the stored pointer. Throws: nothing. Returns: the stored pointer. Throws: nothing. Postconditions: Notes: The returned pointer has an elevated reference count. This
+ allows conversion of an Caution: Using Returns: an unspecified value that, when used in boolean contexts, is
+ equivalent to Throws: nothing. Notes: This conversion operator allows Effects: Exchanges the contents of the two smart pointers. Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Notes: Allows Returns: Throws: nothing. Notes: Allows Effects: Equivalent to Throws: nothing. Notes: Matches the interface of Effects: Equivalent to Throws: nothing. Notes: Matches the interface of Returns: Throws: nothing. Notes: Provided as an aid to generic programming. Used by
- mem_fn. Returns: Throws: nothing. Notes: Provided as an aid to generic programming. Used by
+ mem_fn. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Returns: Throws: nothing. Effects: Returns:
- Copyright © 2003-2005, 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. Effects: Returns: $Date$
+ Copyright © 2003-2005, 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.
Introduction The intrusive_ref_counter class template implements a reference counter for a derived
- user's class that is intended to be used with intrusive_ptr.
+ user's class that is intended to be used with intrusive_ptr.
The base class has associated intrusive_ptr_add_ref and intrusive_ptr_release functions
which modify the reference counter as needed and destroy the user's object when the counter drops to zero. The class template is parameterized on DerivedT and CounterPolicyT parameters.
- The first parameter is the user's class that derives from intrusive_ref_counter. This type
+ The first parameter is the user's class that derives from intrusive_ref_counter. This type
is needed in order to destroy the object correctly when there are no references to it left. The second parameter is a policy that defines the nature of the reference counter.
Boost.SmartPtr provides two such policies: thread_unsafe_counter and thread_safe_counter. The former
@@ -85,11 +85,10 @@
Notes: The returned value may not be actual in multi-threaded applications. $Date$
- $Date$
- Copyright © 2013 Andrey Semashev. 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.
- Smart Pointer Changes
Features Requiring Code Changes to Take Advantage
-
-
- Features That Improve Robustness
-
-
- Implementation Details
-
-
-
-
+ Smart Pointer Changes
Features Requiring Code Changes to Take Advantage
+
+
+ Features That Improve Robustness
+
+
+ Implementation Details
+
+
+
+
-
-
-
-
-
-
-
- enable_shared_from_this.hpp
-
-
-
- Purpose
- Example
-
+
+
+ enable_shared_from_this
Purpose
+ Example
+
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include <cassert>
@@ -51,8 +41,8 @@ int main()
assert(!(p < q || q < p)); // p and q must share ownership
}
- Synopsis
-
+
Synopsis
+
namespace boost
{
@@ -66,30 +56,30 @@ public:
}
- 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;
-
-
-
- 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.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;
+
+
+
- intrusive_ptr class template
- Synopsis
- Members
- Free Functions
- Introduction
- intrusive_ptr
class template stores a pointer to an object with an
- embedded reference count. Every new intrusive_ptr
instance increments
- the reference count by using an unqualified call to the function intrusive_ptr_add_ref
,
- passing it the pointer as an argument. Similarly, when an intrusive_ptr
- is destroyed, it calls intrusive_ptr_release
; this function is
- responsible for destroying the object when its reference count drops to zero.
- The user is expected to provide suitable definitions of these two functions. On
- compilers that support argument-dependent lookup, intrusive_ptr_add_ref
- and intrusive_ptr_release
should be defined in the namespace
- that corresponds to their parameter; otherwise, the definitions need to go in
- namespace boost
. The library provides a helper base class template
- intrusive_ref_counter
which may
- help adding support for intrusive_ptr
to user types.T
, the type of the object pointed
- to. intrusive_ptr<T>
can be implicitly converted to intrusive_ptr<U>
- whenever T*
can be implicitly converted to U*
.intrusive_ptr
are:
-
- intrusive_ptr
- is the same as the corresponding raw pointer;intrusive_ptr<T>
can be constructed from an arbitrary
- raw pointer of type T *
.intrusive_ptr
better
- fits your needs than shared_ptr
, try a shared_ptr
-based
- design first.Synopsis
- namespace boost {
+
+
+ intrusive_ptr class template
+ Synopsis
+ Members
+ Free Functions
+ Introduction
+ intrusive_ptr
class template stores a pointer to an object with an
+ embedded reference count. Every new intrusive_ptr
instance increments
+ the reference count by using an unqualified call to the function intrusive_ptr_add_ref
,
+ passing it the pointer as an argument. Similarly, when an intrusive_ptr
+ is destroyed, it calls intrusive_ptr_release
; this function is
+ responsible for destroying the object when its reference count drops to zero.
+ The user is expected to provide suitable definitions of these two functions. On
+ compilers that support argument-dependent lookup, intrusive_ptr_add_ref
+ and intrusive_ptr_release
should be defined in the namespace
+ that corresponds to their parameter; otherwise, the definitions need to go in
+ namespace boost
. The library provides a helper base class template
+ intrusive_ref_counter
which may
+ help adding support for intrusive_ptr
to user types.T
, the type of the object pointed
+ to. intrusive_ptr<T>
can be implicitly converted to intrusive_ptr<U>
+ whenever T*
can be implicitly converted to U*
.intrusive_ptr
are:
+
+ intrusive_ptr
+ is the same as the corresponding raw pointer;intrusive_ptr<T>
can be constructed from an arbitrary
+ raw pointer of type T *
.intrusive_ptr
better
+ fits your needs than shared_ptr
, try a shared_ptr
-based
+ design first.Synopsis
+ namespace boost {
template<class T> class intrusive_ptr {
@@ -117,203 +117,204 @@
std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p);
}
- Members
- element_type
- typedef T element_type;
-
-
- T
.constructors
- intrusive_ptr(); // never throws
-
-
- get() == 0
.intrusive_ptr(T * p, bool add_ref = true);
-
-
- if(p != 0 && add_ref) intrusive_ptr_add_ref(p);
.get() == p
.intrusive_ptr(intrusive_ptr const & r);
+
Members
+ element_type
+ typedef T element_type;
+
+
+ T
.constructors
+ intrusive_ptr(); // never throws
+
+
+ get() == 0
.intrusive_ptr(T * p, bool add_ref = true);
+
+
+ if(p != 0 && add_ref) intrusive_ptr_add_ref(p);
.get() == p
.intrusive_ptr(intrusive_ptr const & r);
template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);
-
-
- if(r.get() != 0) intrusive_ptr_add_ref(r.get());
.get() == r.get()
.destructor
- ~intrusive_ptr();
-
-
- if(get() != 0) intrusive_ptr_release(get());
.assignment
- intrusive_ptr & operator=(intrusive_ptr const & r);
+
+
+ if(r.get() != 0) intrusive_ptr_add_ref(r.get());
.get() == r.get()
.destructor
+ ~intrusive_ptr();
+
+
+ if(get() != 0) intrusive_ptr_release(get());
.assignment
+ intrusive_ptr & operator=(intrusive_ptr const & r);
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);
intrusive_ptr & operator=(T * r);
-
-
- intrusive_ptr(r).swap(*this)
.*this
.reset
- void reset();
-
-
- intrusive_ptr().swap(*this)
.void reset(T * r);
-
-
- intrusive_ptr(r).swap(*this)
.void reset(T * r, bool add_ref);
-
-
- intrusive_ptr(r, add_ref).swap(*this)
.indirection
- T & operator*() const; // never throws
-
-
- get() != 0
.*get()
.T * operator->() const; // never throws
-
-
- get() != 0
.get()
.get
- T * get() const; // never throws
-
-
- detach
- T * detach(); // never throws
-
-
- get() == 0
.intrusive_ptr
back to a raw pointer,
- without the performance overhead of acquiring and dropping an extra
- reference. It can be viewed as the complement of the
- non-reference-incrementing constructor.detach
escapes the safety of automatic
- reference counting provided by intrusive_ptr
. It should
- by used only where strictly necessary (such as when interfacing to an
- existing API), and when the implications are thoroughly understood.conversions
- operator unspecified-bool-type () const; // never throws
-
-
- get() != 0
.intrusive_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.swap
- void swap(intrusive_ptr & b); // never throws
-
-
- Free Functions
- comparison
- template<class T, class U>
+
+
+ intrusive_ptr(r).swap(*this)
.*this
.reset
+ void reset();
+
+
+ intrusive_ptr().swap(*this)
.void reset(T * r);
+
+
+ intrusive_ptr(r).swap(*this)
.void reset(T * r, bool add_ref);
+
+
+ intrusive_ptr(r, add_ref).swap(*this)
.indirection
+ T & operator*() const; // never throws
+
+
+ get() != 0
.*get()
.T * operator->() const; // never throws
+
+
+ get() != 0
.get()
.get
+ T * get() const; // never throws
+
+
+ detach
+ T * detach(); // never throws
+
+
+ get() == 0
.intrusive_ptr
back to a raw pointer,
+ without the performance overhead of acquiring and dropping an extra
+ reference. It can be viewed as the complement of the
+ non-reference-incrementing constructor.detach
escapes the safety of automatic
+ reference counting provided by intrusive_ptr
. It should
+ by used only where strictly necessary (such as when interfacing to an
+ existing API), and when the implications are thoroughly understood.conversions
+ operator unspecified-bool-type () const; // never throws
+
+
+ get() != 0
.intrusive_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.swap
+ void swap(intrusive_ptr & b); // never throws
+
+
+ Free Functions
+ comparison
+ template<class T, class U>
bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
-
-
- a.get() == b.get()
.template<class T, class U>
+
+
+ a.get() == b.get()
.template<class T, class U>
bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
-
-
- a.get() != b.get()
.template<class T, class U>
+
+
+ a.get() != b.get()
.template<class T, class U>
bool operator==(intrusive_ptr<T> const & a, U * b); // never throws
-
-
- a.get() == b
.template<class T, class U>
+
+
+ a.get() == b
.template<class T, class U>
bool operator!=(intrusive_ptr<T> const & a, U * b); // never throws
-
-
- a.get() != b
.template<class T, class U>
+
+
+ a.get() != b
.template<class T, class U>
bool operator==(T * a, intrusive_ptr<U> const & b); // never throws
-
-
- a == b.get()
.template<class T, class U>
+
+
+ a == b.get()
.template<class T, class U>
bool operator!=(T * a, intrusive_ptr<U> const & b); // never throws
-
-
- a != b.get()
.template<class T, class U>
+
+
+ a != b.get()
.template<class T, class U>
bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
-
-
- std::less<T *>()(a.get(), b.get())
.intrusive_ptr
objects to be used as keys
- in associative containers.swap
- template<class T>
+
+
+ std::less<T *>()(a.get(), b.get())
.intrusive_ptr
objects to be used as keys
+ in associative containers.swap
+ template<class T>
void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b); // never throws
-
-
- a.swap(b)
.std::swap
. Provided as an aid to
- generic programming.get_pointer
- template<class T>
+
+
+ a.swap(b)
.std::swap
. Provided as an aid to
+ generic programming.get_pointer
+ template<class T>
T * get_pointer(intrusive_ptr<T> const & p); // never throws
-
-
- p.get()
.static_pointer_cast
- template<class T, class U>
+
+
+ p.get()
.static_pointer_cast
+ template<class T, class U>
intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & r); // never throws
-
-
- intrusive_ptr<T>(static_cast<T*>(r.get()))
.const_pointer_cast
- template<class T, class U>
+
+
+ intrusive_ptr<T>(static_cast<T*>(r.get()))
.const_pointer_cast
+ template<class T, class U>
intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & r); // never throws
-
-
- intrusive_ptr<T>(const_cast<T*>(r.get()))
.dynamic_pointer_cast
- template<class T, class U>
+
+
+ intrusive_ptr<T>(const_cast<T*>(r.get()))
.dynamic_pointer_cast
+ template<class T, class U>
intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & r);
-
-
- intrusive_ptr<T>(dynamic_cast<T*>(r.get()))
.operator<<
- template<class E, class T, class Y>
+
+
+ intrusive_ptr<T>(dynamic_cast<T*>(r.get()))
.operator<<
+ template<class E, class T, class Y>
std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p);
-
-
- os << p.get();
.os
.
-
+
+ os << p.get();
.os
.
+
+
+ basic_intrusive_ref_counter class template
basic_intrusive_ref_counter class template
Synopsis
@@ -14,11 +14,11 @@
Introduction
+
Introduction
- Synopsis
- Free Functions
- Example
-
Consistent use of shared_ptr
- can eliminate the need to use an explicit delete
,
- but alone it provides no support in avoiding explicit new
.
- There have been repeated requests from users for a factory function that creates
- an object of a given type and returns a shared_ptr
to it.
- Besides convenience and style, such a function is also exception safe and
- considerably faster because it can use a single allocation for both the object
- and its corresponding control block, eliminating a significant portion of
- shared_ptr
's construction overhead.
- This eliminates one of the major efficiency complaints about shared_ptr
.
-
The header file <boost/make_shared.hpp> provides a family of overloaded function templates,
- make_shared
and allocate_shared
, to address this need.
- make_shared
uses the global operator new
to allocate memory,
- whereas allocate_shared
uses an user-supplied allocator, allowing finer control.
- The rationale for choosing the name make_shared
is that the expression
- make_shared<Widget>()
can be read aloud and conveys the intended meaning.
namespace boost { + +-make_shared and allocate_shared + + + ++
make_shared and allocate_shared + function templates
Introduction
+ Synopsis
+ Free Functions
+ Example
+Introduction
+Consistent use of
+shared_ptr
+ can eliminate the need to use an explicitdelete
, + but alone it provides no support in avoiding explicitnew
. + There have been repeated requests from users for a factory function that creates + an object of a given type and returns ashared_ptr
to it. + Besides convenience and style, such a function is also exception safe and + considerably faster because it can use a single allocation for both the object + and its corresponding control block, eliminating a significant portion of +shared_ptr
's construction overhead. + This eliminates one of the major efficiency complaints aboutshared_ptr
. +The header file <boost/make_shared.hpp> provides a family of overloaded function templates, +
+make_shared
andallocate_shared
, to address this need. +make_shared
uses the global operatornew
to allocate memory, + whereasallocate_shared
uses an user-supplied allocator, allowing finer control.+ The rationale for choosing the name
+make_shared
is that the expression +make_shared<Widget>()
can be read aloud and conveys the intended meaning.Synopsis
+namespace boost { template<typename T> class shared_ptr; @@ -41,7 +42,7 @@ template<typename T, typename A> shared_ptr<T> allocate_shared( A const & ); -#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // C++0x prototypes +#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // C++0x prototypes template<typename T, typename... Args> shared_ptr<T> make_shared( Args && ... args ); @@ -69,51 +70,50 @@ #endif }-Free Functions
-template<class T, class... Args> +Free Functions
+template<class T, class... Args> shared_ptr<T> make_shared( Args && ... args ); template<class T, class A, class... Args> shared_ptr<T> allocate_shared( A const & a, Args && ... args );---Requires: The expression
-new( pv ) T( std::forward<Args>(args)... )
, - wherepv
is avoid*
pointing to storage suitable - to hold an object of typeT
, - shall be well-formed.A
shall be an Allocator, - as described in section 20.1.5 (Allocator requirements) of the C++ Standard. - The copy constructor and destructor of A
shall not throw.Effects: Allocates memory suitable for an object of type
-T
- and constructs an object in it via the placement new expressionnew( pv ) T()
- ornew( pv ) T( std::forward<Args>(args)... )
. -allocate_shared
uses a copy ofa
to allocate memory. - If an exception is thrown, has no effect.Returns: A
-shared_ptr
instance that stores and owns the address - of the newly constructed object of typeT
.Postconditions:
-get() != 0 && use_count() == 1
.Throws:
-bad_alloc
, or an exception thrown fromA::allocate
- or the constructor ofT
.Notes: This implementation allocates the memory required for the - returned
-shared_ptr
and an object of typeT
in a single - allocation. This provides efficiency equivalent to an intrusive smart pointer.The prototypes shown above are used if your compiler supports rvalue references - and variadic templates. They perfectly forward the
-args
parameters to - the constructors ofT
.Otherwise, the implementation will fall back on - forwarding the arguments to the constructors of
-T
as const references. - If you need to pass a non-const reference to a constructor ofT
, - you may do so by wrapping the parameter in a call toboost::ref
. - In addition, you will be - limited to a maximum of 9 arguments (not counting the allocator argument of - allocate_shared).Example
-boost::shared_ptr<std::string> x = boost::make_shared<std::string>("hello, world!"); +++Requires: The expression
+new( pv ) T( std::forward<Args>(args)... )
, + wherepv
is avoid*
pointing to storage suitable + to hold an object of typeT
, + shall be well-formed.A
shall be an Allocator, + as described in section 20.1.5 (Allocator requirements) of the C++ Standard. + The copy constructor and destructor ofA
shall not throw.Effects: Allocates memory suitable for an object of type
+T
+ and constructs an object in it via the placement new expressionnew( pv ) T()
+ ornew( pv ) T( std::forward<Args>(args)... )
. +allocate_shared
uses a copy ofa
to allocate memory. + If an exception is thrown, has no effect.Returns: A
+shared_ptr
instance that stores and owns the address + of the newly constructed object of typeT
.Postconditions:
+get() != 0 && use_count() == 1
.Throws:
+bad_alloc
, or an exception thrown fromA::allocate
+ or the constructor ofT
.Notes: This implementation allocates the memory required for the + returned
+shared_ptr
and an object of typeT
in a single + allocation. This provides efficiency equivalent to an intrusive smart pointer.The prototypes shown above are used if your compiler supports rvalue references + and variadic templates. They perfectly forward the
+args
parameters to + the constructors ofT
.Otherwise, the implementation will fall back on + forwarding the arguments to the constructors of
+T
as const references. + If you need to pass a non-const reference to a constructor ofT
, + you may do so by wrapping the parameter in a call toboost::ref
. + In addition, you will be + limited to a maximum of 9 arguments (not counting the allocator argument of + allocate_shared).Example
+boost::shared_ptr<std::string> x = boost::make_shared<std::string>("hello, world!"); std::cout << *x;-
-- $Date: 2008-05-19 15:42:39 -0400 (Mon, 19 May 2008) $
-Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess. - 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.
- +
+$Date$
+Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess. + 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/make_shared_array.html b/make_shared_array.html index 28a7a11..6c323b8 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -250,8 +250,10 @@ boost::shared_ptr<int[4][2]> a2 = boost::make_shared_noinit<int[4][2]&gHistory
-January 2014. Glen Fernandes reduced the overloads of make_shared and - allocate_shared according to N3870.
+February 2014. Glen Fernandes updated overloads of make_shared and + allocate_shared to conform to the specification in C++ standard paper + N3870 including resolving C++ standard library + defect report 2070.
November 2012. Glen Fernandes contributed implementations of make_shared and allocate_shared for arrays.
References
@@ -260,7 +262,7 @@ boost::shared_ptr<int[4][2]> a2 = boost::make_shared_noinit<int[4][2]&g Extending make_shared to Support Arrays, Revision 1, Peter Dimov & Glen Fernandes, January, 2014.
-$Date: 2014-01-20 11:10:00 -0800 (Mon, 20 Jan 2014) $
+$Date$
Copyright 2012-2014 Glen Fernandes. Distributed under the Boost Software License, Version 1.0. See accompanying file LICENSE_1_0.txt or copy at diff --git a/make_unique.html b/make_unique.html index f1246db..c3e6ab8 100644 --- a/make_unique.html +++ b/make_unique.html @@ -142,7 +142,7 @@ unique_ptr<int[][2]> p2 = boost::make_unique_noinit<int[][2]>(2);
January 2014. Glen Fernandes contributed implementations of make_unique for objects and arrays.
-$Date: 2014-01-20 11:10:00 -0800 (Mon, 20 Jan 2014) $
+$Date$
Copyright 2012-2014 Glen Fernandes. Distributed under the Boost Software License, Version 1.0. See accompanying file LICENSE_1_0.txt or copy at diff --git a/pointer_cast.html b/pointer_cast.html index 8f14795..2ab0859 100644 --- a/pointer_cast.html +++ b/pointer_cast.html @@ -1,33 +1,34 @@ - + - -
pointer_cast.hpp - - --
Pointer - cast functions
The pointer cast functions (
-boost::static_pointer_cast
boost::dynamic_pointer_cast
-boost::reinterpret_pointer_cast
boost::const_pointer_cast
) - provide a way to write generic pointer castings for raw pointers. The functions - are defined in boost/pointer_cast.hpp.There is test/example code in pointer_cast_test.cpp.
-Rationale
-Boost smart pointers usually overload those functions to provide a mechanism to - emulate pointers casts. For example,
-boost::shared_ptr<...>
implements - a static pointer cast this way:+ +pointer_cast + + + ++
pointer_cast
The pointer cast functions (
+boost::static_pointer_cast
boost::dynamic_pointer_cast
+boost::reinterpret_pointer_cast
boost::const_pointer_cast
) + provide a way to write generic pointer castings for raw pointers. The functions + are defined in boost/pointer_cast.hpp.There is test/example code in pointer_cast_test.cpp.
+Rationale
+Boost smart pointers usually overload those functions to provide a mechanism to + emulate pointers casts. For example,
+boost::shared_ptr<...>
implements + a static pointer cast this way:template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const &r);-Pointer cast functions from boost/pointer_cast.hpp - are overloads of
-boost::static_pointer_cast
,boost::dynamic_pointer_cast
, -boost::reinterpret_pointer_cast
andboost::const_pointer_cast
- for raw pointers. This way when developing pointer type independent classes, - for example, memory managers or shared memory compatible classes, the same code - can be used for raw and smart pointers.Synopsis
--++Pointer cast functions from boost/pointer_cast.hpp + are overloads of
+boost::static_pointer_cast
,boost::dynamic_pointer_cast
, +boost::reinterpret_pointer_cast
andboost::const_pointer_cast
+ for raw pointers. This way when developing pointer type independent classes, + for example, memory managers or shared memory compatible classes, the same code + can be used for raw and smart pointers.Synopsis
++-namespace boost { template<class T, class U> @@ -48,12 +49,12 @@ inline T* reinterpret_pointer_cast(U *ptr) } // namespace boost-As you can see from the above synopsis, the pointer cast functions are just - wrappers around standard C++ cast operators.
-Example
--++As you can see from the above synopsis, the pointer cast functions are just + wrappers around standard C++ cast operators.
+Example
++-#include <boost/pointer_cast.hpp> #include <boost/shared_ptr.hpp> @@ -93,13 +94,13 @@ int main() delete ptr; return 0; }-The example demonstrates how the generic pointer casts help us create pointer - independent code.
-
-Revised: $Date$
-Copyright 2005 Ion Gaztañaga. Use, modification, and distribution are subject to - the Boost Software License, Version 1.0. (See accompanying file - LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
- +The example demonstrates how the generic pointer casts help us create pointer + independent code.
+
+$Date$
+Copyright 2005 Ion Gaztañaga. Use, modification, and distribution are subject to + the Boost Software License, Version 1.0. (See accompanying file + LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
+ diff --git a/pointer_to_other.html b/pointer_to_other.html index e6b138c..e9be750 100644 --- a/pointer_to_other.html +++ b/pointer_to_other.html @@ -1,33 +1,33 @@ - -pointer_to_other.hpp - - - --
Header - boost/pointer_to_other.hpp
- The pointer to other utility provides a way, given a source pointer type, - to obtain a pointer of the same type to another pointee type. The utility is - defined in boost/pointer_to_other.hpp.
-There is test/example code in pointer_to_other_test.cpp.
-Contents
-
When building pointer independent classes, like memory managers, allocators, or - containers, there is often a need to define pointers generically, so that if a - template parameter represents a pointer (for example, a raw or smart pointer to - an int), we can define another pointer of the same type to another pointee (a - raw or smart pointer to a float.)
-template <class IntPtr> + ++pointer_to_other + + + ++
pointer_to_other
+ The pointer to other utility provides a way, given a source pointer type, + to obtain a pointer of the same type to another pointee type. The utility is + defined in boost/pointer_to_other.hpp.
+There is test/example code in pointer_to_other_test.cpp.
+Contents
+
When building pointer independent classes, like memory managers, allocators, or + containers, there is often a need to define pointers generically, so that if a + template parameter represents a pointer (for example, a raw or smart pointer to + an int), we can define another pointer of the same type to another pointee (a + raw or smart pointer to a float.)
+template <class IntPtr> class FloatPointerHolder { // Let's define a pointer to a float @@ -35,8 +35,8 @@ class FloatPointerHolder <IntPtr, float>::type float_ptr_t; float_ptr_t float_ptr; };-
+Synopsis
+namespace boost { template<class T, class U> @@ -69,10 +69,10 @@ struct pointer_to_other< T*, U > }; } // namespace boost-If these definitions are not correct for a specific smart pointer, we can define - a specialization of pointer_to_other.
-Example
-// Let's define a memory allocator that can +If these definitions are not correct for a specific smart pointer, we can define + a specialization of pointer_to_other.
+Example
+// Let's define a memory allocator that can // work with raw and smart pointers #include <boost/pointer_to_other.hpp> @@ -97,12 +97,12 @@ class memory_allocator block_ptr_t free_blocks; };-As we can see, using pointer_to_other we can create pointer independent code.
-
-Last revised: $Date$
-Copyright 2005, 2006 Ion Gaztañaga and Peter Dimov. Use, modification, - and distribution are subject to the Boost Software License, Version 1.0.
- +
- (See accompanying file LICENSE_1_0.txt or a - copy at < http://www.boost.org/LICENSE_1_0.txt>.)As we can see, using pointer_to_other we can create pointer independent code.
+
+$Date$
+Copyright 2005, 2006 Ion Gaztañaga and Peter Dimov. Use, modification, + and distribution are subject to the Boost Software License, Version 1.0.
+ diff --git a/scoped_array.htm b/scoped_array.htm index 2d03509..3624e5d 100644 --- a/scoped_array.htm +++ b/scoped_array.htm @@ -1,38 +1,38 @@ - + - -
+ (See accompanying file LICENSE_1_0.txt or a + copy at < http://www.boost.org/LICENSE_1_0.txt>.)scoped_array - - - --
scoped_array class template
The scoped_array class template stores a pointer to a dynamically - allocated array. (Dynamically allocated arrays are allocated with the C++ new[] - expression.) The array pointed to is guaranteed to be deleted, either on - destruction of the scoped_array, or via an explicit reset.
-The scoped_array template is a simple solution for simple needs. It - supplies a basic "resource acquisition is initialization" facility, without - shared-ownership or transfer-of-ownership semantics. Both its name and - enforcement of semantics (by being - noncopyable) signal its intent to retain ownership solely within the - current scope. Because it is noncopyable, - it is safer than shared_array for pointers which should not be copied.
-Because scoped_array is so simple, in its usual implementation every - operation is as fast as a built-in array pointer and it has no more space - overhead that a built-in array pointer.
-It cannot be used in C++ standard library containers. See - shared_array if scoped_array does not meet your needs.
-It cannot correctly hold a pointer to a single object. See scoped_ptr - for that usage.
-A std::vector is an alternative to a scoped_array that is a bit - heavier duty but far more flexible. A boost::array is an alternative - that does not use dynamic allocation.
-The class template is parameterized on T, the type of the object pointed - to. T must meet the smart pointer - common requirements.
-Synopsis
-namespace boost { + +scoped_array + + + ++
scoped_array class template
The scoped_array class template stores a pointer to a dynamically + allocated array. (Dynamically allocated arrays are allocated with the C++ new[] + expression.) The array pointed to is guaranteed to be deleted, either on + destruction of the scoped_array, or via an explicit reset.
+The scoped_array template is a simple solution for simple needs. It + supplies a basic "resource acquisition is initialization" facility, without + shared-ownership or transfer-of-ownership semantics. Both its name and + enforcement of semantics (by being + noncopyable) signal its intent to retain ownership solely within the + current scope. Because it is noncopyable, + it is safer than shared_array for pointers which should not be copied.
+Because scoped_array is so simple, in its usual implementation every + operation is as fast as a built-in array pointer and it has no more space + overhead that a built-in array pointer.
+It cannot be used in C++ standard library containers. See + shared_array if scoped_array does not meet your needs.
+It cannot correctly hold a pointer to a single object. See scoped_ptr + for that usage.
+A std::vector is an alternative to a scoped_array that is a bit + heavier duty but far more flexible. A boost::array is an alternative + that does not use dynamic allocation.
+The class template is parameterized on T, the type of the object pointed + to. T must meet the smart pointer + common requirements.
+Synopsis
+namespace boost { template<class T> class scoped_array : noncopyable { @@ -55,62 +55,61 @@ template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b); // never throws }-Members
-- element_type
-typedef T element_type;-Provides the type of the stored pointer.
-constructors
-explicit scoped_array(T * p = 0); // never throws-Constructs a scoped_array, storing a copy of p, which must have - been allocated via a C++ new[] expression or be 0. T is not - required be a complete type. See the smart pointer - common requirements.
-destructor
-~scoped_array(); // never throws-Deletes the array pointed to by the stored pointer. Note that delete[] on - a pointer with a value of 0 is harmless. The guarantee that this does not throw - exceptions depends on the requirement that the deleted array's objects' - destructors do not throw exceptions. See the smart pointer - common requirements.
-reset
-void reset(T * p = 0); // never throws-- Deletes the array pointed to by the stored pointer and then stores a copy of p, - which must have been allocated via a C++ new[] expression or be 0. The - guarantee that this does not throw exceptions depends on the requirement that - the deleted array's objects' destructors do not throw exceptions. See the smart - pointer common requirements.
-subscripting
-T & operator[](std::ptrdiff_t i) const; // never throws-Returns a reference to element i of the array pointed to by the stored - pointer. Behavior is undefined and almost certainly undesirable if the stored - pointer is 0, or if i is less than 0 or is greater than or equal to the - number of elements in the array.
-get
-T * get() const; // never throws-Returns the stored pointer. T need not be a complete type. See the smart - pointer common requirements.
-conversions
-operator unspecified-bool-type () const; // never throws-Returns an unspecified value that, when used in boolean contexts, is equivalent - to
-get() != 0
.swap
-void swap(scoped_array & b); // never throws-Exchanges the contents of the two smart pointers. T need not be a - complete type. See the smart pointer common - requirements.
-Free Functions
-swap
-template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b); // never throws-Equivalent to a.swap(b). Matches the interface of std::swap. - Provided as an aid to generic programming.
-
-Revised - 09 January 2003
-Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - Copyright 2002-2005 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.
- +Members
++ element_type
+typedef T element_type;+Provides the type of the stored pointer.
+constructors
+explicit scoped_array(T * p = 0); // never throws+Constructs a scoped_array, storing a copy of p, which must have + been allocated via a C++ new[] expression or be 0. T is not + required be a complete type. See the smart pointer + common requirements.
+destructor
+~scoped_array(); // never throws+Deletes the array pointed to by the stored pointer. Note that delete[] on + a pointer with a value of 0 is harmless. The guarantee that this does not throw + exceptions depends on the requirement that the deleted array's objects' + destructors do not throw exceptions. See the smart pointer + common requirements.
+reset
+void reset(T * p = 0); // never throws++ Deletes the array pointed to by the stored pointer and then stores a copy of p, + which must have been allocated via a C++ new[] expression or be 0. The + guarantee that this does not throw exceptions depends on the requirement that + the deleted array's objects' destructors do not throw exceptions. See the smart + pointer common requirements.
+subscripting
+T & operator[](std::ptrdiff_t i) const; // never throws+Returns a reference to element i of the array pointed to by the stored + pointer. Behavior is undefined and almost certainly undesirable if the stored + pointer is 0, or if i is less than 0 or is greater than or equal to the + number of elements in the array.
+get
+T * get() const; // never throws+Returns the stored pointer. T need not be a complete type. See the smart + pointer common requirements.
+conversions
+operator unspecified-bool-type () const; // never throws+Returns an unspecified value that, when used in boolean contexts, is equivalent + to
+get() != 0
.swap
+void swap(scoped_array & b); // never throws+Exchanges the contents of the two smart pointers. T need not be a + complete type. See the smart pointer common + requirements.
+Free Functions
+swap
+template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b); // never throws+Equivalent to a.swap(b). Matches the interface of std::swap. + Provided as an aid to generic programming.
+
+$Date$
+Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. + Copyright 2002-2005 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/scoped_ptr.htm b/scoped_ptr.htm index fc5785c..1dbfbce 100644 --- a/scoped_ptr.htm +++ b/scoped_ptr.htm @@ -1,38 +1,38 @@ - + - -scoped_ptr - - - --
scoped_ptr class template
The scoped_ptr class template stores a pointer to a dynamically allocated - object. (Dynamically allocated objects are allocated with the C++ new expression.) - The object pointed to is guaranteed to be deleted, either on destruction of the scoped_ptr, - or via an explicit reset. See the example.
-The scoped_ptr template is a simple solution for simple needs. It - supplies a basic "resource acquisition is initialization" facility, without - shared-ownership or transfer-of-ownership semantics. Both its name and - enforcement of semantics (by being - noncopyable) signal its intent to retain ownership solely within the - current scope. Because it is noncopyable, - it is safer than shared_ptr or std::auto_ptr for pointers which - should not be copied.
-Because scoped_ptr is simple, in its usual implementation every operation - is as fast as for a built-in pointer and it has no more space overhead that a - built-in pointer.
-scoped_ptr cannot be used in C++ Standard Library containers. - Use shared_ptr if you need a smart pointer - that can.
-scoped_ptr cannot correctly hold a pointer to a dynamically - allocated array. See scoped_array for - that usage.
-The class template is parameterized on T, the type of the object pointed - to. T must meet the smart pointer - common requirements.
-Synopsis
-namespace boost { + +scoped_ptr + + + ++
scoped_ptr class template
The scoped_ptr class template stores a pointer to a dynamically allocated + object. (Dynamically allocated objects are allocated with the C++ new expression.) + The object pointed to is guaranteed to be deleted, either on destruction of the scoped_ptr, + or via an explicit reset. See the example.
+The scoped_ptr template is a simple solution for simple needs. It + supplies a basic "resource acquisition is initialization" facility, without + shared-ownership or transfer-of-ownership semantics. Both its name and + enforcement of semantics (by being + noncopyable) signal its intent to retain ownership solely within the + current scope. Because it is noncopyable, + it is safer than shared_ptr or std::auto_ptr for pointers which + should not be copied.
+Because scoped_ptr is simple, in its usual implementation every operation + is as fast as for a built-in pointer and it has no more space overhead that a + built-in pointer.
+scoped_ptr cannot be used in C++ Standard Library containers. + Use shared_ptr if you need a smart pointer + that can.
+scoped_ptr cannot correctly hold a pointer to a dynamically + allocated array. See scoped_array for + that usage.
+The class template is parameterized on T, the type of the object pointed + to. T must meet the smart pointer + common requirements.
+Synopsis
+namespace boost { template<class T> class scoped_ptr : noncopyable { @@ -56,60 +56,60 @@ template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws }-Members
-element_type
-typedef T element_type;-Provides the type of the stored pointer.
-constructors
-explicit scoped_ptr(T * p = 0); // never throws-Constructs a scoped_ptr, storing a copy of p, which must have been - allocated via a C++ new expression or be 0. T is not required be - a complete type. See the smart pointer common - requirements.
-destructor
-~scoped_ptr(); // never throws-Destroys the object pointed to by the stored pointer, if any, as if by using delete - this->get().
-- The guarantee that this does not throw exceptions depends on the requirement - that the deleted object's destructor does not throw exceptions. See the smart - pointer common requirements.
-reset
-void reset(T * p = 0); // never throws-- Deletes the object pointed to by the stored pointer and then stores a copy of - p, which must have been allocated via a C++ new expression or be 0. The - guarantee that this does not throw exceptions depends on the requirement that - the deleted object's destructor does not throw exceptions. See the smart - pointer common requirements.
-indirection
-T & operator*() const; // never throws-Returns a reference to the object pointed to by the stored pointer. Behavior is - undefined if the stored pointer is 0.
-T * operator->() const; // never throws-Returns the stored pointer. Behavior is undefined if the stored pointer is 0.
-get
-T * get() const; // never throws-Returns the stored pointer. T need not be a complete type. See the smart - pointer common requirements.
-conversions
-operator unspecified-bool-type () const; // never throws-Returns an unspecified value that, when used in boolean contexts, is equivalent - to
-get() != 0
.swap
-void swap(scoped_ptr & b); // never throws-Exchanges the contents of the two smart pointers. T need not be a - complete type. See the smart pointer common - requirements.
-Free Functions
-swap
-template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws-Equivalent to a.swap(b). Matches the interface of std::swap. - Provided as an aid to generic programming.
-Example
-Here's an example that uses scoped_ptr.
--+#include <boost/scoped_ptr.hpp> +Members
+element_type
+typedef T element_type;+Provides the type of the stored pointer.
+constructors
+explicit scoped_ptr(T * p = 0); // never throws+Constructs a scoped_ptr, storing a copy of p, which must have been + allocated via a C++ new expression or be 0. T is not required be + a complete type. See the smart pointer common + requirements.
+destructor
+~scoped_ptr(); // never throws+Destroys the object pointed to by the stored pointer, if any, as if by using delete + this->get().
++ The guarantee that this does not throw exceptions depends on the requirement + that the deleted object's destructor does not throw exceptions. See the smart + pointer common requirements.
+reset
+void reset(T * p = 0); // never throws++ Deletes the object pointed to by the stored pointer and then stores a copy of + p, which must have been allocated via a C++ new expression or be 0. The + guarantee that this does not throw exceptions depends on the requirement that + the deleted object's destructor does not throw exceptions. See the smart + pointer common requirements.
+indirection
+T & operator*() const; // never throws+Returns a reference to the object pointed to by the stored pointer. Behavior is + undefined if the stored pointer is 0.
+T * operator->() const; // never throws+Returns the stored pointer. Behavior is undefined if the stored pointer is 0.
+get
+T * get() const; // never throws+Returns the stored pointer. T need not be a complete type. See the smart + pointer common requirements.
+conversions
+operator unspecified-bool-type () const; // never throws+Returns an unspecified value that, when used in boolean contexts, is equivalent + to
+get() != 0
.swap
+void swap(scoped_ptr & b); // never throws+Exchanges the contents of the two smart pointers. T need not be a + complete type. See the smart pointer common + requirements.
+Free Functions
+swap
+template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws+Equivalent to a.swap(b). Matches the interface of std::swap. + Provided as an aid to generic programming.
+Example
+Here's an example that uses scoped_ptr.
++-#include <boost/scoped_ptr.hpp> #include <iostream> struct Shoe { ~Shoe() { std::cout << "Buckle my shoe\n"; } }; @@ -128,54 +128,53 @@ int main() std::cout << my_instance.add_one() << '\n'; std::cout << my_instance.add_one() << '\n'; }-The example program produces the beginning of a child's nursery rhyme:
--+1 +The example program produces the beginning of a child's nursery rhyme:
++-1 2 Buckle my shoe-Rationale
-The primary reason to use scoped_ptr rather than auto_ptr is to - let readers of your code know that you intend "resource acquisition is - initialization" to be applied only for the current scope, and have no intent to - transfer ownership.
-A secondary reason to use scoped_ptr is to prevent a later maintenance - programmer from adding a function that transfers ownership by returning the auto_ptr, - because the maintenance programmer saw auto_ptr, and assumed ownership - could safely be transferred.
-Think of bool vs int. We all know that under the covers bool - is usually just an int. Indeed, some argued against including bool - in the C++ standard because of that. But by coding bool rather than int, - you tell your readers what your intent is. Same with scoped_ptr; by - using it you are signaling intent.
-It has been suggested that scoped_ptr<T> is equivalent to std::auto_ptr<T> - const. Ed Brey pointed out, however, that reset will not work on - a std::auto_ptr<T> const.
-Handle/Body Idiom
-One common usage of scoped_ptr is to implement a handle/body (also called - pimpl) idiom which avoids exposing the body (implementation) in the header - file.
-The scoped_ptr_example_test.cpp - sample program includes a header file, scoped_ptr_example.hpp, - which uses a scoped_ptr<> to an incomplete type to hide the - implementation. The instantiation of member functions which require a complete - type occurs in the scoped_ptr_example.cpp - implementation file.
-Frequently Asked Questions
-Q. Why doesn't scoped_ptr have a release() member?
-
- A. When reading source code, it is valuable to be able to draw - conclusions about program behavior based on the types being used. If scoped_ptr - had a release() member, it would become possible to transfer ownership of the - held pointer, weakening its role as a way of limiting resource lifetime to a - given context. Use std::auto_ptr where transfer of ownership - is required. (supplied by Dave Abrahams)
-Revised - 09 January 2003
-Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - Copyright 2002-2005 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.
- +Rationale
+The primary reason to use scoped_ptr rather than auto_ptr is to + let readers of your code know that you intend "resource acquisition is + initialization" to be applied only for the current scope, and have no intent to + transfer ownership.
+A secondary reason to use scoped_ptr is to prevent a later maintenance + programmer from adding a function that transfers ownership by returning the auto_ptr, + because the maintenance programmer saw auto_ptr, and assumed ownership + could safely be transferred.
+Think of bool vs int. We all know that under the covers bool + is usually just an int. Indeed, some argued against including bool + in the C++ standard because of that. But by coding bool rather than int, + you tell your readers what your intent is. Same with scoped_ptr; by + using it you are signaling intent.
+It has been suggested that scoped_ptr<T> is equivalent to std::auto_ptr<T> + const. Ed Brey pointed out, however, that reset will not work on + a std::auto_ptr<T> const.
+Handle/Body Idiom
+One common usage of scoped_ptr is to implement a handle/body (also called + pimpl) idiom which avoids exposing the body (implementation) in the header + file.
+The scoped_ptr_example_test.cpp + sample program includes a header file, scoped_ptr_example.hpp, + which uses a scoped_ptr<> to an incomplete type to hide the + implementation. The instantiation of member functions which require a complete + type occurs in the scoped_ptr_example.cpp + implementation file.
+Frequently Asked Questions
+Q. Why doesn't scoped_ptr have a release() member?
+
+ A. When reading source code, it is valuable to be able to draw + conclusions about program behavior based on the types being used. If scoped_ptr + had a release() member, it would become possible to transfer ownership of the + held pointer, weakening its role as a way of limiting resource lifetime to a + given context. Use std::auto_ptr where transfer of ownership + is required. (supplied by Dave Abrahams)
+$Date
+Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. + Copyright 2002-2005 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/shared_array.htm b/shared_array.htm index 320a54a..4c31458 100644 --- a/shared_array.htm +++ b/shared_array.htm @@ -1,35 +1,35 @@ - + - -shared_array - - - --
shared_array class template
The shared_array class template stores a pointer to a dynamically - allocated array. (Dynamically allocated array are allocated with the C++ new[] - expression.) The object pointed to is guaranteed to be deleted when the last shared_array - pointing to it is destroyed or reset.
-Every shared_array meets the CopyConstructible and Assignable - requirements of the C++ Standard Library, and so can be used in standard - library containers. Comparison operators are supplied so that shared_array - works with the standard library's associative containers.
-Normally, a shared_array cannot correctly hold a pointer to an object - that has been allocated with the non-array form of new. See - shared_ptr for that usage.
-Because the implementation uses reference counting, cycles of shared_array - instances will not be reclaimed. For example, if main() holds a shared_array - to A, which directly or indirectly holds a shared_array back to A, - A's use count will be 2. Destruction of the original shared_array - will leave A dangling with a use count of 1.
-A shared_ptr to a std::vector is an alternative to a shared_array - that is a bit heavier duty but far more flexible.
-The class template is parameterized on T, the type of the object pointed - to. T must meet the smart pointer - common requirements.
-Synopsis
-namespace boost { + +shared_array + + + ++
shared_array class template
The shared_array class template stores a pointer to a dynamically + allocated array. (Dynamically allocated array are allocated with the C++ new[] + expression.) The object pointed to is guaranteed to be deleted when the last shared_array + pointing to it is destroyed or reset.
+Every shared_array meets the CopyConstructible and Assignable + requirements of the C++ Standard Library, and so can be used in standard + library containers. Comparison operators are supplied so that shared_array + works with the standard library's associative containers.
+Normally, a shared_array cannot correctly hold a pointer to an object + that has been allocated with the non-array form of new. See + shared_ptr for that usage.
+Because the implementation uses reference counting, cycles of shared_array + instances will not be reclaimed. For example, if main() holds a shared_array + to A, which directly or indirectly holds a shared_array back to A, + A's use count will be 2. Destruction of the original shared_array + will leave A dangling with a use count of 1.
+A shared_ptr to a std::vector is an alternative to a shared_array + that is a bit heavier duty but far more flexible.
+The class template is parameterized on T, the type of the object pointed + to. T must meet the smart pointer + common requirements.
+Synopsis
+namespace boost { template<class T> class shared_array { @@ -68,118 +68,116 @@ template<class T> void swap(shared_array<T> & a, shared_array<T> & b); // never throws }-Members
-element_type
-typedef T element_type;-Provides the type of the stored pointer.
-constructors
-explicit shared_array(T * p = 0);-Constructs a shared_array, storing a copy of p, which must be a - pointer to an array that was allocated via a C++ new[] expression or be - 0. Afterwards, the use count is 1 (even if p == 0; see - ~shared_array). The only exception which may be thrown by this - constructor is std::bad_alloc. If an exception is thrown, delete[] p - is called.
-template<class D> shared_array(T * p, D d);-Constructs a shared_array, storing a copy of p and of d. - Afterwards, the use count is 1. D's copy - constructor and destructor must not throw. When the the time comes to delete - the array pointed to by p, the object d is used in the statement d(p). - Invoking the object d with parameter p in this way must not - throw. The only exception which may be thrown by this constructor is std::bad_alloc. - If an exception is thrown, d(p) is called.
-shared_array(shared_array const & r); // never throws-Constructs a shared_array, as if by storing a copy of the pointer stored - in r. Afterwards, the use count for all copies - is 1 more than the initial use count.
-destructor
-~shared_array(); // never throws-Decrements the use count. Then, if the use count is 0, - deletes the array pointed to by the stored pointer. Note that delete[] on - a pointer with a value of 0 is harmless. T need not be a complete type. - The guarantee that this 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_array & operator=(shared_array const & r); // never throws-Constructs a new shared_array as described above, - then replaces this shared_array with the new one, destroying the - replaced object.
-reset
-void reset(T * p = 0);-Constructs a new shared_array as described above, - then replaces this shared_array with the new one, destroying the - replaced object. The only exception which may be thrown is std::bad_alloc. - If an exception is thrown, delete[] p is called.
-template<class D> void reset(T * p, D d);-Constructs a new shared_array as described above, - then replaces this shared_array with the new one, destroying the - replaced object. D's copy constructor must not throw. The only exception - which may be thrown is std::bad_alloc. If an exception is thrown, d(p) - is called.
-indexing
-T & operator[](std::ptrdiff_t i) const; // never throws-Returns a reference to element i of the array pointed to by the stored - pointer. Behavior is undefined and almost certainly undesirable if the stored - pointer is 0, or if i is less than 0 or is greater than or equal to the - number of elements in the array.
-get
-T * get() const; // never throws-Returns the stored pointer. T need not be a complete type. See the smart - pointer common requirements.
-unique
-bool unique() const; // never throws-Returns true if no other shared_array is sharing ownership of the stored - pointer, false otherwise. T need not be a complete type. See the smart - pointer common requirements.
-use_count
-long use_count() const; // never throws-Returns the number of shared_array objects sharing ownership of the - stored pointer. T need not be a complete type. See the smart pointer - common requirements.
-Because use_count is not necessarily efficient to implement for - implementations of shared_array that do not use an explicit reference - count, it might be removed from some future version. Thus it should be used for - debugging purposes only, and not production code.
-conversions
-operator unspecified-bool-type () const; // never throws-Returns an unspecified value that, when used in boolean contexts, is equivalent - to
-get() != 0
.swap
-void swap(shared_ptr & b); // never throws-Exchanges the contents of the two smart pointers. T need not be a - complete type. See the smart pointer common - requirements.
-Free Functions
-comparison
-template<class T> +Members
+element_type
+typedef T element_type;+Provides the type of the stored pointer.
+constructors
+explicit shared_array(T * p = 0);+Constructs a shared_array, storing a copy of p, which must be a + pointer to an array that was allocated via a C++ new[] expression or be + 0. Afterwards, the use count is 1 (even if p == 0; see + ~shared_array). The only exception which may be thrown by this + constructor is std::bad_alloc. If an exception is thrown, delete[] p + is called.
+template<class D> shared_array(T * p, D d);+Constructs a shared_array, storing a copy of p and of d. + Afterwards, the use count is 1. D's copy + constructor and destructor must not throw. When the the time comes to delete + the array pointed to by p, the object d is used in the statement d(p). + Invoking the object d with parameter p in this way must not + throw. The only exception which may be thrown by this constructor is std::bad_alloc. + If an exception is thrown, d(p) is called.
+shared_array(shared_array const & r); // never throws+Constructs a shared_array, as if by storing a copy of the pointer stored + in r. Afterwards, the use count for all copies + is 1 more than the initial use count.
+destructor
+~shared_array(); // never throws+Decrements the use count. Then, if the use count is 0, + deletes the array pointed to by the stored pointer. Note that delete[] on + a pointer with a value of 0 is harmless. T need not be a complete type. + The guarantee that this 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_array & operator=(shared_array const & r); // never throws+Constructs a new shared_array as described above, + then replaces this shared_array with the new one, destroying the + replaced object.
+reset
+void reset(T * p = 0);+Constructs a new shared_array as described above, + then replaces this shared_array with the new one, destroying the + replaced object. The only exception which may be thrown is std::bad_alloc. + If an exception is thrown, delete[] p is called.
+template<class D> void reset(T * p, D d);+Constructs a new shared_array as described above, + then replaces this shared_array with the new one, destroying the + replaced object. D's copy constructor must not throw. The only exception + which may be thrown is std::bad_alloc. If an exception is thrown, d(p) + is called.
+indexing
+T & operator[](std::ptrdiff_t i) const; // never throws+Returns a reference to element i of the array pointed to by the stored + pointer. Behavior is undefined and almost certainly undesirable if the stored + pointer is 0, or if i is less than 0 or is greater than or equal to the + number of elements in the array.
+get
+T * get() const; // never throws+Returns the stored pointer. T need not be a complete type. See the smart + pointer common requirements.
+unique
+bool unique() const; // never throws+Returns true if no other shared_array is sharing ownership of the stored + pointer, false otherwise. T need not be a complete type. See the smart + pointer common requirements.
+use_count
+long use_count() const; // never throws+Returns the number of shared_array objects sharing ownership of the + stored pointer. T need not be a complete type. See the smart pointer + common requirements.
+Because use_count is not necessarily efficient to implement for + implementations of shared_array that do not use an explicit reference + count, it might be removed from some future version. Thus it should be used for + debugging purposes only, and not production code.
+conversions
+operator unspecified-bool-type () const; // never throws+Returns an unspecified value that, when used in boolean contexts, is equivalent + to
+get() != 0
.swap
+void swap(shared_ptr & b); // never throws+Exchanges the contents of the two smart pointers. T need not be a + complete type. See the smart pointer common + requirements.
+Free Functions
+comparison
+template<class T> bool operator==(shared_array<T> const & a, shared_array<T> const & b); // never throws template<class T> bool operator!=(shared_array<T> const & a, shared_array<T> const & b); // never throws template<class T> bool operator<(shared_array<T> const & a, shared_array<T> const & b); // never throws-Compares the stored pointers of the two smart pointers. T need not be a - complete type. See the smart pointer common - requirements.
-The operator< overload is provided to define an ordering so that shared_array - objects can be used in associative containers such as std::map. The - implementation uses std::less<T *> to perform the comparison. This - ensures that the comparison is handled correctly, since the standard mandates - that relational operations on pointers are unspecified (5.9 [expr.rel] - paragraph 2) but std::less<> on pointers is well-defined (20.3.3 - [lib.comparisons] paragraph 8).
-swap
-template<class T> +Compares the stored pointers of the two smart pointers. T need not be a + complete type. See the smart pointer common + requirements.
+The operator< overload is provided to define an ordering so that shared_array + objects can be used in associative containers such as std::map. The + implementation uses std::less<T *> to perform the comparison. This + ensures that the comparison is handled correctly, since the standard mandates + that relational operations on pointers are unspecified (5.9 [expr.rel] + paragraph 2) but std::less<> on pointers is well-defined (20.3.3 + [lib.comparisons] paragraph 8).
+swap
+template<class T> void swap(shared_array<T> & a, shared_array<T> & b) // never throws-Equivalent to a.swap(b). Matches the interface of std::swap. - Provided as an aid to generic programming.
-
-Revised - - 09 January 2003
-Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - Copyright 2002-2005 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.
- +Equivalent to a.swap(b). Matches the interface of std::swap. + Provided as an aid to generic programming.
+
+$Date
+Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. + Copyright 2002-2005 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/shared_ptr.htm b/shared_ptr.htm index 0043200..d58e1f5 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -1,85 +1,86 @@ - + - -shared_ptr - - - -boost::shared_ptr class template
-Introduction
-
- Best Practices
- Synopsis
- Members
- Free Functions
- Example
- Handle/Body Idiom
- Thread Safety
- Frequently Asked Questions
- Smart Pointer Timings
- Programming TechniquesIntroduction
-The
-shared_ptr
class template stores a pointer to a dynamically allocated - object, typically with a C++ new-expression. The object pointed to is - guaranteed to be deleted when the lastshared_ptr
pointing to it is - destroyed or reset.Example:shared_ptr<X> p1( new X ); + +shared_ptr + + + ++
shared_ptr class template
Introduction
+
+ Best Practices
+ Synopsis
+ Members
+ Free Functions
+ Example
+ Handle/Body Idiom
+ Thread Safety
+ Frequently Asked Questions
+ Smart Pointer Timings
+ Programming TechniquesIntroduction
+The
+shared_ptr
class template stores a pointer to a dynamically allocated + object, typically with a C++ new-expression. The object pointed to is + guaranteed to be deleted when the lastshared_ptr
pointing to it is + destroyed or reset.Example:-shared_ptr<X> p1( new X ); shared_ptr<void> p2( new int(5) );+
shared_ptr
deletes the exact pointer that has been passed at construction time, - complete with its original type, regardless of the template parameter. In the second example above, - whenp2
is destroyed or reset, it will calldelete
on the originalint*
- that has been passed to the constructor, even thoughp2
itself is of type -shared_ptr<void>
and stores a pointer of typevoid*
.-
shared_ptr
deletes the exact pointer that has been passed at construction time, + complete with its original type, regardless of the template parameter. In the second example above, + whenp2
is destroyed or reset, it will calldelete
on the originalint*
+ that has been passed to the constructor, even thoughp2
itself is of type +shared_ptr<void>
and stores a pointer of typevoid*
.Every
-shared_ptr
meets theCopyConstructible
,MoveConstructible
, -CopyAssignable
andMoveAssignable
- requirements of the C++ Standard Library, and can be used in standard - library containers. Comparison operators are supplied so thatshared_ptr
- works with the standard library's associative containers.Because the implementation uses reference counting, cycles of
-shared_ptr
instances - will not be reclaimed. For example, ifmain()
holds ashared_ptr
to -A
, which directly or indirectly holds ashared_ptr
back toA
, -A
's use count will be 2. Destruction of the originalshared_ptr
will - leaveA
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.shared_ptr
and most of its member functions place no - requirements onT
; 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 toshared_ptr<U>
- wheneverT*
can be implicitly converted toU*
. - In particular,shared_ptr<T>
is implicitly convertible - toshared_ptr<T const>
, toshared_ptr<U>
- whereU
is an accessible base ofT
, and to- shared_ptr<void>
.-
shared_ptr
is now part of the C++11 Standard, asstd::shared_ptr
.Starting with Boost release 1.53,
-shared_ptr
can be used to hold a pointer to a dynamically - allocated array. This is accomplished by using an array type (T[]
orT[N]
) as - the template parameter. There is almost no difference between using an unsized array,T[]
, - and a sized array,T[N]
; the latter just enablesoperator[]
to perform a range check - on the index.Example:shared_ptr<double[1024]> p1( new double[1024] ); +Every
+shared_ptr
meets theCopyConstructible
,MoveConstructible
, +CopyAssignable
andMoveAssignable
+ requirements of the C++ Standard Library, and can be used in standard + library containers. Comparison operators are supplied so thatshared_ptr
+ works with the standard library's associative containers.Because the implementation uses reference counting, cycles of
+shared_ptr
instances + will not be reclaimed. For example, ifmain()
holds ashared_ptr
to +A
, which directly or indirectly holds ashared_ptr
back toA
, +A
's use count will be 2. Destruction of the originalshared_ptr
will + leaveA
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.shared_ptr
and most of its member functions place no + requirements onT
; 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 toshared_ptr<U>
+ wheneverT*
can be implicitly converted toU*
. + In particular,shared_ptr<T>
is implicitly convertible + toshared_ptr<T const>
, toshared_ptr<U>
+ whereU
is an accessible base ofT
, and to+ shared_ptr<void>
.+
shared_ptr
is now part of the C++11 Standard, asstd::shared_ptr
.Starting with Boost release 1.53,
+shared_ptr
can be used to hold a pointer to a dynamically + allocated array. This is accomplished by using an array type (T[]
orT[N]
) as + the template parameter. There is almost no difference between using an unsized array,T[]
, + and a sized array,T[N]
; the latter just enablesoperator[]
to perform a range check + on the index.Example:-shared_ptr<double[1024]> p1( new double[1024] ); shared_ptr<double[]> p2( new double[n] );Best Practices
-A simple guideline that nearly eliminates the possibility of memory leaks is: - always use a named smart pointer variable to hold the result of
-new
. - Every occurence of thenew
keyword in the code should have the - form:shared_ptr<T> p(new Y);-It is, of course, acceptable to use another smart pointer in place of
-shared_ptr
- above; havingT
andY
be the same type, or - passing arguments toY
's constructor is also OK.If you observe this guideline, it naturally follows that you will have no - explicit
-delete
statements;try/catch
constructs will - be rare.Avoid using unnamed
-shared_ptr
temporaries to save typing; to - see why this is dangerous, consider this example:void f(shared_ptr<int>, int); +Best Practices
+A simple guideline that nearly eliminates the possibility of memory leaks is: + always use a named smart pointer variable to hold the result of
+new
. + Every occurence of thenew
keyword in the code should have the + form:shared_ptr<T> p(new Y);+It is, of course, acceptable to use another smart pointer in place of
+shared_ptr
+ above; havingT
andY
be the same type, or + passing arguments toY
's constructor is also OK.If you observe this guideline, it naturally follows that you will have no + explicit
+delete
statements;try/catch
constructs will + be rare.Avoid using unnamed
+shared_ptr
temporaries to save typing; to + see why this is dangerous, consider this example:void f(shared_ptr<int>, int); int g(); void ok() @@ -93,21 +94,21 @@ void bad() f( shared_ptr<int>( new int(2) ), g() ); }-The function
ok
follows the guideline to the letter, whereas -bad
constructs the temporaryshared_ptr
in place, - admitting the possibility of a memory leak. Since function arguments are - evaluated in unspecified order, it is possible fornew int(2)
to - be evaluated first,g()
second, and we may never get to the +The function
-ok
follows the guideline to the letter, whereas +bad
constructs the temporaryshared_ptr
in place, + admitting the possibility of a memory leak. Since function arguments are + evaluated in unspecified order, it is possible fornew int(2)
to + be evaluated first,g()
second, and we may never get to theshared_ptr
constructor ifg
throws an exception. - See Herb Sutter's treatment (also - here) of the issue for more information.The exception safety problem described above may also be eliminated by using - the
-make_shared
- orallocate_shared
- factory functions defined inboost/make_shared.hpp
. - These factory functions also provide an efficiency benefit by consolidating allocations.Synopsis
-namespace boost { + See Herb Sutter's treatment (also + here) of the issue for more information. +The exception safety problem described above may also be eliminated by using + the
+make_shared
+ orallocate_shared
+ factory functions defined inboost/make_shared.hpp
. + These factory functions also provide an efficiency benefit by consolidating allocations.Synopsis
+namespace boost { class bad_weak_ptr: public std::exception; @@ -227,479 +228,479 @@ void bad() template<class D, class T> D * get_deleter(shared_ptr<T> const & p); }-Members
-element_type
-typedef ... element_type;--+
element_type
isT
whenT
is not an array type, +Members
+element_type
+typedef ... element_type;++--
element_type
isT
whenT
is not an array type, andU
whenT
isU[]
orU[N]
.default constructor
-shared_ptr(); // never throws +default constructor
+shared_ptr(); // never throws shared_ptr(std::nullptr_t); // never throws---Effects: Constructs an empty
-shared_ptr
.Postconditions:
-use_count() == 0 && get() == 0
.Throws: nothing.
-[The nothrow guarantee is important, since
-reset()
is specified - in terms of the default constructor; this implies that the constructor must not - allocate memory.]pointer constructor
-template<class Y> explicit shared_ptr(Y * p);--+Requirements: -
-Y
must be a complete type. - The expressiondelete[] p
, whenT
is an array type, ordelete p
, - whenT
is not an array type, - must be well-formed, must not invoke undefined behavior, and must not throw exceptions. - WhenT
isU[N]
,Y (*) [N]
must be convertible toT*
; - whenT
isU[]
,Y (*) []
must be convertible toT*
; - otherwise,Y*
must be convertible toT*
. -Effects: - When
+T
is not an array type, constructs ashared_ptr
that owns - the pointerp
. - Otherwise, constructs ashared_ptr
that owns -p
and a deleter of an unspecified type that callsdelete[] p
.++Effects: Constructs an empty
+shared_ptr
.Postconditions:
+use_count() == 0 && get() == 0
.Throws: nothing.
+[The nothrow guarantee is important, since
+reset()
is specified + in terms of the default constructor; this implies that the constructor must not + allocate memory.]pointer constructor
+template<class Y> explicit shared_ptr(Y * p);++-Requirements: +
+Y
must be a complete type. + The expressiondelete[] p
, whenT
is an array type, ordelete p
, + whenT
is not an array type, + must be well-formed, must not invoke undefined behavior, and must not throw exceptions. + WhenT
isU[N]
,Y (*) [N]
must be convertible toT*
; + whenT
isU[]
,Y (*) []
must be convertible toT*
; + otherwise,Y*
must be convertible toT*
. +Effects: + When
T
is not an array type, constructs ashared_ptr
that owns + the pointerp
. + Otherwise, constructs ashared_ptr
that owns +p
and a deleter of an unspecified type that callsdelete[] p
.Postconditions:
use_count() == 1 && get() == p
. IfT
is not an array type andp
is unambiguously convertible toenable_shared_from_this<V>*
for someV
,p->shared_from_this()
returns a copy of*this
.Throws:
-std::bad_alloc
, or an implementation-defined - exception when a resource other than memory could not be obtained.Exception safety: If an exception is thrown, the constructor calls -
-delete[] p
, whenT
is an array type, - ordelete p
, whenT
is not an array type.Notes:
-p
must be a pointer to an object that was - allocated via a C++new
expression or be 0. The postcondition that - use count is 1 holds even ifp
is 0; invokingdelete
- on a pointer that has a value of 0 is harmless.[This constructor is a template in order to remember the actual - pointer type passed. The destructor will call
-delete
with the - same pointer, complete with its original type, even whenT
does - not have a virtual destructor, or isvoid
.]constructors taking a deleter
-template<class Y, class D> shared_ptr(Y * p, D d); + exception when a resource other than memory could not be obtained. +Exception safety: If an exception is thrown, the constructor calls +
+delete[] p
, whenT
is an array type, + ordelete p
, whenT
is not an array type.Notes:
+p
must be a pointer to an object that was + allocated via a C++new
expression or be 0. The postcondition that + use count is 1 holds even ifp
is 0; invokingdelete
+ on a pointer that has a value of 0 is harmless.[This constructor is a template in order to remember the actual + pointer type passed. The destructor will call
+delete
with the + same pointer, complete with its original type, even whenT
does + not have a virtual destructor, or isvoid
.]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 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 beCopyConstructible
. The copy constructor and destructor - ofD
must not throw. The expressiond(p)
must be - well-formed, must not invoke undefined behavior, and must not throw exceptions. -A
must be an Allocator, as described in section 20.1.5 - (Allocator requirements
) of the C++ Standard. - WhenT
isU[N]
,Y (*) [N]
must be convertible toT*
; - whenT
isU[]
,Y (*) []
must be convertible toT*
; - otherwise,Y*
must be convertible toT*
. -Effects: Constructs a
+shared_ptr
that owns the pointer- p
and the deleterd
. The constructors taking an allocatora
- allocate memory using a copy ofa
.+-Requirements: +
+D
must beCopyConstructible
. The copy constructor and destructor + ofD
must not throw. The expressiond(p)
must be + well-formed, must not invoke undefined behavior, and must not throw exceptions. +A
must be an Allocator, as described in section 20.1.5 + (Allocator requirements
) of the C++ Standard. + WhenT
isU[N]
,Y (*) [N]
must be convertible toT*
; + whenT
isU[]
,Y (*) []
must be convertible toT*
; + otherwise,Y*
must be convertible toT*
. +Effects: Constructs a
shared_ptr
that owns the pointer+ p
and the deleterd
. The constructors taking an allocatora
+ allocate memory using a copy ofa
.Postconditions:
-use_count() == 1 && get() == p
. IfT
is not an array type andp
is unambiguously convertible toenable_shared_from_this<V>*
for someV
,p->shared_from_this()
returns a copy of*this
.Throws:
-std::bad_alloc
, or an implementation-defined - exception when a resource other than memory could not be obtained.Exception safety: If an exception is thrown,
-d(p)
is called.Notes: When the the time comes to delete the object pointed to by
-p
, - the stored copy ofd
is invoked with the stored copy ofp
- as an argument.[Custom deallocators allow a factory function returning a
-shared_ptr
- to insulate the user from its memory allocation strategy. Since the deallocator - is not part of the type, changing the allocation strategy does not break source - or binary compatibility, and does not require a client recompilation. For - example, a "no-op" deallocator is useful when returning ashared_ptr
- to a statically allocated object, and other variations allow ashared_ptr
- to be used as a wrapper for another smart pointer, easing interoperability.The support for custom deallocators does not impose significant overhead. Other
-- shared_ptr
features still require a deallocator to be kept.The requirement that the copy constructor of
-D
does not throw comes from - the pass by value. If the copy constructor throws, the pointer would leak.]copy and converting constructors
-shared_ptr(shared_ptr const & r); // never throws +Throws:
+std::bad_alloc
, or an implementation-defined + exception when a resource other than memory could not be obtained.Exception safety: If an exception is thrown,
+d(p)
is called.Notes: When the the time comes to delete the object pointed to by
+p
, + the stored copy ofd
is invoked with the stored copy ofp
+ as an argument.[Custom deallocators allow a factory function returning a
+shared_ptr
+ to insulate the user from its memory allocation strategy. Since the deallocator + is not part of the type, changing the allocation strategy does not break source + or binary compatibility, and does not require a client recompilation. For + example, a "no-op" deallocator is useful when returning ashared_ptr
+ to a statically allocated object, and other variations allow ashared_ptr
+ to be used as a wrapper for another smart pointer, easing interoperability.The support for custom deallocators does not impose significant overhead. Other
++ shared_ptr
features still require a deallocator to be kept.The requirement that the copy constructor of
+D
does not throw comes from + the pass by value. If the copy constructor throws, the pointer would leak.]copy and converting constructors
+shared_ptr(shared_ptr const & r); // never throws template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws---Requires:
-Y*
should be convertible toT*
.Effects: If
-r
is empty, constructs an emptyshared_ptr
; - otherwise, constructs ashared_ptr
that shares ownership withr
.Postconditions:
-get() == r.get() && use_count() == - r.use_count()
.Throws: nothing.
-move constructors
-shared_ptr(shared_ptr && r); // never throws +++Requires:
+Y*
should be convertible toT*
.Effects: If
+r
is empty, constructs an emptyshared_ptr
; + otherwise, constructs ashared_ptr
that shares ownership withr
.Postconditions:
+get() == r.get() && use_count() == + r.use_count()
.Throws: nothing.
+move constructors
+shared_ptr(shared_ptr && r); // never throws template<class Y> shared_ptr(shared_ptr<Y> && r); // never throws---Requires:
-Y*
should be convertible toT*
.Effects: Move-constructs a
-shared_ptr
fromr
.Postconditions:
-*this
contains the old value ofr
.r
is empty andr.get() == 0
.Throws: nothing.
-aliasing constructor
-template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p); // never throws---Effects: constructs a
-shared_ptr
that shares ownership with -r
and storesp
.Postconditions:
-get() == p && use_count() == r.use_count()
.Throws: nothing.
-weak_ptr constructor
-template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);---Requires:
-Y*
should be convertible toT*
.Effects: Constructs a
-shared_ptr
that shares ownership with -r
and stores a copy of the pointer stored inr
.Postconditions:
-use_count() == r.use_count()
.Throws:
-bad_weak_ptr
whenr.use_count() == 0
.Exception safety: If an exception is thrown, the constructor has no - effect.
-auto_ptr constructors
-template<class Y> shared_ptr(std::auto_ptr<Y> & r); +++Requires:
+Y*
should be convertible toT*
.Effects: Move-constructs a
+shared_ptr
fromr
.Postconditions:
+*this
contains the old value ofr
.r
is empty andr.get() == 0
.Throws: nothing.
+aliasing constructor
+template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p); // never throws+++Effects: constructs a
+shared_ptr
that shares ownership with +r
and storesp
.Postconditions:
+get() == p && use_count() == r.use_count()
.Throws: nothing.
+weak_ptr constructor
+template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);+++Requires:
+Y*
should be convertible toT*
.Effects: Constructs a
+shared_ptr
that shares ownership with +r
and stores a copy of the pointer stored inr
.Postconditions:
+use_count() == r.use_count()
.Throws:
+bad_weak_ptr
whenr.use_count() == 0
.Exception safety: If an exception is thrown, the constructor has no + effect.
+auto_ptr constructors
+template<class Y> shared_ptr(std::auto_ptr<Y> & r); template<class Y> shared_ptr(std::auto_ptr<Y> && r);---Requires:
-Y*
should be convertible toT*
.Effects: Constructs a
-shared_ptr
, as if by storing a copy ofr.release()
.Postconditions:
-use_count() == 1
.Throws:
-std::bad_alloc
, or an implementation-defined - exception when a resource other than memory could not be obtained.Exception safety: If an exception is thrown, the constructor has no - effect.
-unique_ptr constructor
-template<class Y, class D> shared_ptr(std::unique_ptr<Y, D> && r);---Requires:
-Y*
should be convertible toT*
.Effects: - Equivalent to
-shared_ptr(r.release(), r.get_deleter())
whenD
is not a reference type. - Otherwise, equivalent toshared_ptr(r.release(), del)
, where del is a deleter - that stores the referencerd
returned fromr.get_deleter()
anddel(p)
callsrd(p)
.Postconditions:
-use_count() == 1
.Throws:
-std::bad_alloc
, or an implementation-defined - exception when a resource other than memory could not be obtained.Exception safety: If an exception is thrown, the constructor has no - effect.
-destructor
-~shared_ptr(); // never throws---Effects:
--
-- - If
-*this
is empty, or shares ownership with - anothershared_ptr
instance (use_count() > 1
), - there are no side effects.- - Otherwise, if
-*this
owns a pointerp
- and a deleterd
,d(p)
- is called.- - Otherwise,
-*this
owns a pointerp
, - anddelete p
is called.Throws: nothing.
-assignment
-shared_ptr & operator=(shared_ptr const & r); // never throws +++Requires:
+Y*
should be convertible toT*
.Effects: Constructs a
+shared_ptr
, as if by storing a copy ofr.release()
.Postconditions:
+use_count() == 1
.Throws:
+std::bad_alloc
, or an implementation-defined + exception when a resource other than memory could not be obtained.Exception safety: If an exception is thrown, the constructor has no + effect.
+unique_ptr constructor
+template<class Y, class D> shared_ptr(std::unique_ptr<Y, D> && r);+++Requires:
+Y*
should be convertible toT*
.Effects: + Equivalent to
+shared_ptr(r.release(), r.get_deleter())
whenD
is not a reference type. + Otherwise, equivalent toshared_ptr(r.release(), del)
, where del is a deleter + that stores the referencerd
returned fromr.get_deleter()
anddel(p)
callsrd(p)
.Postconditions:
+use_count() == 1
.Throws:
+std::bad_alloc
, or an implementation-defined + exception when a resource other than memory could not be obtained.Exception safety: If an exception is thrown, the constructor has no + effect.
+destructor
+~shared_ptr(); // never throws+++Effects:
++
+- + If
+*this
is empty, or shares ownership with + anothershared_ptr
instance (use_count() > 1
), + there are no side effects.- + Otherwise, if
+*this
owns a pointerp
+ and a deleterd
,d(p)
+ is called.- + Otherwise,
+*this
owns a pointerp
, + anddelete p
is called.Throws: nothing.
+assignment
+shared_ptr & operator=(shared_ptr const & r); // never throws template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);--+Effects: Equivalent to
-shared_ptr(r).swap(*this)
.Returns:
-*this
.Notes: The use count updates caused by the temporary object construction - and destruction are not considered observable side effects, and the - implementation is free to meet the effects (and the implied guarantees) via - different means, without creating a temporary. In particular, in the example:
-shared_ptr<int> p(new int); ++-Effects: Equivalent to
+shared_ptr(r).swap(*this)
.Returns:
+*this
.Notes: The use count updates caused by the temporary object construction + and destruction are not considered observable side effects, and the + implementation is free to meet the effects (and the implied guarantees) via + different means, without creating a temporary. In particular, in the example:
+shared_ptr<int> p(new int); shared_ptr<void> q(p); p = p; q = p;-both assignments may be no-ops.
-shared_ptr & operator=(shared_ptr && r); // never throws +both assignments may be no-ops.
+shared_ptr & operator=(shared_ptr && r); // never throws template<class Y> shared_ptr & operator=(shared_ptr<Y> && r); // never throws 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)
.Returns:
-*this
.shared_ptr & operator=(std::nullptr_t); // never throws---Effects: Equivalent to
-shared_ptr().swap(*this)
.Returns:
-*this
.reset
-void reset(); // never throws---Effects: Equivalent to
-shared_ptr().swap(*this)
.template<class Y> void reset(Y * p);---Effects: Equivalent to
-shared_ptr(p).swap(*this)
.template<class Y, class D> void reset(Y * p, D d);---Effects: Equivalent to
-shared_ptr(p, d).swap(*this)
.template<class Y, class D, class A> void reset(Y * p, D d, A a);---Effects: Equivalent to
-shared_ptr(p, d, a).swap(*this)
.template<class Y> void reset(shared_ptr<Y> const & r, element_type * p); // never throws---Effects: Equivalent to
-shared_ptr(r, p).swap(*this)
.indirection
-T & operator*() const; // never throws---Requirements:
-T
should not be an array type. The stored pointer must not be 0.Returns: a reference to the object pointed to by the stored pointer.
-Throws: nothing.
-T * operator->() const; // never throws---Requirements:
-T
should not be an array type. The stored pointer must not be 0.Returns: the stored pointer.
-Throws: nothing.
-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
. IfT
isU[N]
,i < N
.Returns:
-get()[i]
.Throws: nothing.
-get
-element_type * get() const; // never throws---Returns: the stored pointer.
-Throws: nothing.
-unique
-bool unique() const; // never throws---Returns:
-use_count() == 1
.Throws: nothing.
-Notes:
-unique()
may be faster thanuse_count()
. - If you are usingunique()
to implement copy on write, do not rely - on a specific value when the stored pointer is zero.use_count
-long use_count() const; // never throws---Returns: the number of
-shared_ptr
objects,*this
included, - that share ownership with*this
, or 0 when*this
- is empty.Throws: nothing.
-Notes:
-use_count()
is not necessarily efficient. Use only - for debugging and testing purposes, not for production code.conversions
-explicit operator bool() const; // never throws---Returns:
-get() != 0
.Throws: nothing.
-Notes: This conversion operator allows
-shared_ptr
objects to be - used in boolean contexts, likeif(p && p->valid()) {}
.[The conversion to bool is not merely syntactic sugar. It allows
-shared_ptr
s - to be declared in conditions when using dynamic_pointer_cast - or weak_ptr::lock.]swap
-void swap(shared_ptr & b); // never throws---Effects: Exchanges the contents of the two smart pointers.
-Throws: nothing.
-swap
+++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
+void reset(); // never throws+++Effects: Equivalent to
+shared_ptr().swap(*this)
.template<class Y> void reset(Y * p);+++Effects: Equivalent to
+shared_ptr(p).swap(*this)
.template<class Y, class D> void reset(Y * p, D d);+++Effects: Equivalent to
+shared_ptr(p, d).swap(*this)
.template<class Y, class D, class A> void reset(Y * p, D d, A a);+++Effects: Equivalent to
+shared_ptr(p, d, a).swap(*this)
.template<class Y> void reset(shared_ptr<Y> const & r, element_type * p); // never throws+++Effects: Equivalent to
+shared_ptr(r, p).swap(*this)
.indirection
+T & operator*() const; // never throws+++Requirements:
+T
should not be an array type. The stored pointer must not be 0.Returns: a reference to the object pointed to by the stored pointer.
+Throws: nothing.
+T * operator->() const; // never throws+++Requirements:
+T
should not be an array type. The stored pointer must not be 0.Returns: the stored pointer.
+Throws: nothing.
+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
. IfT
isU[N]
,i < N
.Returns:
+get()[i]
.Throws: nothing.
+get
+element_type * get() const; // never throws+++Returns: the stored pointer.
+Throws: nothing.
+unique
+bool unique() const; // never throws+++Returns:
+use_count() == 1
.Throws: nothing.
+Notes:
+unique()
may be faster thanuse_count()
. + If you are usingunique()
to implement copy on write, do not rely + on a specific value when the stored pointer is zero.use_count
+long use_count() const; // never throws+++Returns: the number of
+shared_ptr
objects,*this
included, + that share ownership with*this
, or 0 when*this
+ is empty.Throws: nothing.
+Notes:
+use_count()
is not necessarily efficient. Use only + for debugging and testing purposes, not for production code.conversions
+explicit operator bool() const; // never throws+++Returns:
+get() != 0
.Throws: nothing.
+Notes: This conversion operator allows
+shared_ptr
objects to be + used in boolean contexts, likeif(p && p->valid()) {}
.[The conversion to bool is not merely syntactic sugar. It allows
+shared_ptr
s + to be declared in conditions when using dynamic_pointer_cast + or weak_ptr::lock.]swap
+void swap(shared_ptr & b); // never throws+++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> +++Effects: See the description of
+operator<
.Throws: nothing.
+Free Functions
+comparison
+template<class T, class U> bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws---Returns:
-a.get() == b.get()
.Throws: nothing.
-template<class T, class U> +++Returns:
+a.get() == b.get()
.Throws: nothing.
+template<class T, class U> bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws--+Returns:
-a.get() != b.get()
.Throws: nothing.
-+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.
-+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> +++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---Returns: an unspecified value such that
--
-- -
-operator<
is a strict weak ordering as described in section 25.3[lib.alg.sorting]
- of the C++ standard;- - under the equivalence relation defined by
operator<
,!(a - < b) && !(b < a)
, twoshared_ptr
instances - are equivalent if and only if they share ownership or are both empty.Throws: nothing.
-Notes: Allows
-shared_ptr
objects to be used as keys in - associative containers.[
-Operator<
has been preferred over astd::less
- specialization for consistency and legality reasons, asstd::less
- is required to return the results ofoperator<
, and many - standard algorithms useoperator<
instead ofstd::less
- for comparisons when a predicate is not supplied. Composite objects, likestd::pair
, - also implement theiroperator<
in terms of their contained - subobjects'operator<
.The rest of the comparison operators are omitted by design.]
-swap
-template<class T> +++Returns: an unspecified value such that
++
+- +
+operator<
is a strict weak ordering as described in section 25.3[lib.alg.sorting]
+ of the C++ standard;- + under the equivalence relation defined by
operator<
,!(a + < b) && !(b < a)
, twoshared_ptr
instances + are equivalent if and only if they share ownership or are both empty.Throws: nothing.
+Notes: Allows
+shared_ptr
objects to be used as keys in + associative containers.[
+Operator<
has been preferred over astd::less
+ specialization for consistency and legality reasons, asstd::less
+ is required to return the results ofoperator<
, and many + standard algorithms useoperator<
instead ofstd::less
+ for comparisons when a predicate is not supplied. Composite objects, likestd::pair
, + also implement theiroperator<
in terms of their contained + subobjects'operator<
.The rest of the comparison operators are omitted by design.]
+swap
+template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws---Effects: Equivalent to
-a.swap(b)
.Throws: nothing.
-Notes: Matches the interface of
-std::swap
. Provided as an aid to - generic programming.[
-swap
is defined in the same namespace asshared_ptr
- as this is currently the only legal way to supply aswap
function - that has a chance to be used by the standard library.]get_pointer
-template<class T> +++Effects: Equivalent to
+a.swap(b)
.Throws: nothing.
+Notes: Matches the interface of
+std::swap
. Provided as an aid to + generic programming.[
+swap
is defined in the same namespace asshared_ptr
+ as this is currently the only legal way to supply aswap
function + that has a chance to be used by the standard library.]get_pointer
+template<class T> typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p); // never throws---Returns:
-p.get()
.Throws: nothing.
-Notes: Provided as an aid to generic programming. Used by - mem_fn.
-static_pointer_cast
-template<class T, class U> +++Returns:
+p.get()
.Throws: nothing.
+Notes: Provided as an aid to generic programming. Used by + mem_fn.
+static_pointer_cast
+template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws---Requires: The expression
-static_cast<T*>( (U*)0 )
- must be well-formed.Returns:
-shared_ptr<T>( r, static_cast<typename shared_ptr<T>::element_type*>(r.get()) )
.Throws: nothing.
-Notes: the seemingly equivalent expression -
-shared_ptr<T>(static_cast<T*>(r.get()))
- will eventually result in undefined behavior, attempting to delete the same - object twice.const_pointer_cast
-template<class T, class U> +++Requires: The expression
+static_cast<T*>( (U*)0 )
+ must be well-formed.Returns:
+shared_ptr<T>( r, static_cast<typename shared_ptr<T>::element_type*>(r.get()) )
.Throws: nothing.
+Notes: the seemingly equivalent expression +
+shared_ptr<T>(static_cast<T*>(r.get()))
+ will eventually result in undefined behavior, attempting to delete the same + object twice.const_pointer_cast
+template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws---Requires: The expression
-const_cast<T*>( (U*)0 )
- must be well-formed.Returns:
-shared_ptr<T>( r, const_cast<typename shared_ptr<T>::element_type*>(r.get()) )
.Throws: nothing.
-dynamic_pointer_cast
-template<class T, class U> +++Requires: The expression
+const_cast<T*>( (U*)0 )
+ must be well-formed.Returns:
+shared_ptr<T>( r, const_cast<typename shared_ptr<T>::element_type*>(r.get()) )
.Throws: nothing.
+dynamic_pointer_cast
+template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r);---Requires: The expression
-dynamic_cast<T*>( (U*)0 )
- must be well-formed.Returns:
--
-- - When
-dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())
returns a nonzero valuep
, -shared_ptr<T>(r, p)
;- - Otherwise,
shared_ptr<T>()
.Throws: nothing.
-reinterpret_pointer_cast
-template<class T, class U> +++Requires: The expression
+dynamic_cast<T*>( (U*)0 )
+ must be well-formed.Returns:
++
+- + When
+dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())
returns a nonzero valuep
, +shared_ptr<T>(r, p)
;- + Otherwise,
shared_ptr<T>()
.Throws: nothing.
+reinterpret_pointer_cast
+template<class T, class U> shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U> const & r); // never throws---Requires: The expression
-reinterpret_cast<T*>( (U*)0 )
- must be well-formed.Returns:
-shared_ptr<T>( r, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()) )
.Throws: nothing.
-operator<<
-template<class E, class T, class Y> +++Requires: The expression
+reinterpret_cast<T*>( (U*)0 )
+ must be well-formed.Returns:
+shared_ptr<T>( r, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()) )
.Throws: nothing.
+operator<<
+template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);---Effects:
-os << p.get();
.Returns:
-os
.get_deleter
-template<class D, class T> +++Effects:
+os << p.get();
.Returns:
+os
.get_deleter
+template<class D, class T> D * get_deleter(shared_ptr<T> const & p);---Returns: If
-*this
owns a deleterd
- of type (cv-unqualified)D
, returns&d
; - otherwise returns 0.Throws: nothing.
-Example
-See shared_ptr_example.cpp for a - complete example program. The program builds a
-std::vector
andstd::set
- ofshared_ptr
objects.Note that after the containers have been populated, some of the
-shared_ptr
- objects will have a use count of 1 rather than a use count of 2, since the set - is astd::set
rather than astd::multiset
, and thus does not - contain duplicate entries. Furthermore, the use count may be even higher at - various times whilepush_back
andinsert
container operations are - performed. More complicated yet, the container operations may throw exceptions - under a variety of circumstances. Getting the memory management and exception - handling in this example right without a smart pointer would be a nightmare.Handle/Body Idiom
-One common usage of
-shared_ptr
is to implement a handle/body (also called - pimpl) idiom which avoids exposing the body (implementation) in the header - file.The shared_ptr_example2_test.cpp - sample program includes a header file, shared_ptr_example2.hpp, - which uses a
-shared_ptr
to an incomplete type to hide the - implementation. The instantiation of member functions which require a complete - type occurs in the shared_ptr_example2.cpp - implementation file. Note that there is no need for an explicit destructor. - Unlike~scoped_ptr
,~shared_ptr
does not require thatT
be a complete - type.Thread Safety
--
shared_ptr
objects offer the same level of thread safety as - built-in types. Ashared_ptr
instance can be "read" (accessed - using only const operations) simultaneously by multiple threads. Differentshared_ptr
- instances can be "written to" (accessed using mutable operations such asoperator= -
orreset
) simultaneously by multiple threads (even - when these instances are copies, and share the same reference count - underneath.)Any other simultaneous accesses result in undefined behavior.
-Examples:
-shared_ptr<int> p(new int(42)); +++Returns: If
+*this
owns a deleterd
+ of type (cv-unqualified)D
, returns&d
; + otherwise returns 0.Throws: nothing.
+Example
+See shared_ptr_example.cpp for a + complete example program. The program builds a
+std::vector
andstd::set
+ ofshared_ptr
objects.Note that after the containers have been populated, some of the
+shared_ptr
+ objects will have a use count of 1 rather than a use count of 2, since the set + is astd::set
rather than astd::multiset
, and thus does not + contain duplicate entries. Furthermore, the use count may be even higher at + various times whilepush_back
andinsert
container operations are + performed. More complicated yet, the container operations may throw exceptions + under a variety of circumstances. Getting the memory management and exception + handling in this example right without a smart pointer would be a nightmare.Handle/Body Idiom
+One common usage of
+shared_ptr
is to implement a handle/body (also called + pimpl) idiom which avoids exposing the body (implementation) in the header + file.The shared_ptr_example2_test.cpp + sample program includes a header file, shared_ptr_example2.hpp, + which uses a
+shared_ptr
to an incomplete type to hide the + implementation. The instantiation of member functions which require a complete + type occurs in the shared_ptr_example2.cpp + implementation file. Note that there is no need for an explicit destructor. + Unlike~scoped_ptr
,~shared_ptr
does not require thatT
be a complete + type.Thread Safety
++
shared_ptr
objects offer the same level of thread safety as + built-in types. Ashared_ptr
instance can be "read" (accessed + using only const operations) simultaneously by multiple threads. Differentshared_ptr
+ instances can be "written to" (accessed using mutable operations such asoperator= +
orreset
) simultaneously by multiple threads (even + when these instances are copies, and share the same reference count + underneath.)Any other simultaneous accesses result in undefined behavior.
+Examples:
+shared_ptr<int> p(new int(42)); //--- Example 1 --- @@ -741,104 +742,105 @@ p3.reset(new int(1)); // thread B p3.reset(new int(2)); // undefined, multiple writes--
Starting with Boost release 1.33.0,
-shared_ptr
uses a lock-free - implementation on most common platforms.If your program is single-threaded and does not link to any libraries that might - have used
-shared_ptr
in its default configuration, you can- #define
the macroBOOST_SP_DISABLE_THREADS
on a - project-wide basis to switch to ordinary non-atomic reference count updates.(Defining
-BOOST_SP_DISABLE_THREADS
in some, but not all, - translation units is technically a violation of the One Definition Rule and - undefined behavior. Nevertheless, the implementation attempts to do its best to - accommodate the request to use non-atomic updates in those translation units. - No guarantees, though.)You can define the macro
-BOOST_SP_USE_PTHREADS
to turn off the - lock-free platform-specific implementation and fall back to the generic -pthread_mutex_t
-based code.Frequently Asked Questions
-Q. There are several variations of shared pointers, with different - tradeoffs; why does the smart pointer library supply only a single - implementation? It would be useful to be able to experiment with each type so - as to find the most suitable for the job at hand?
-- A. An important goal of
-shared_ptr
is to provide a - standard shared-ownership pointer. Having a single pointer type is important - for stable library interfaces, since different shared pointers typically cannot - interoperate, i.e. a reference counted pointer (used by library A) cannot share - ownership with a linked pointer (used by library B.) -Q. Why doesn't
-shared_ptr
have template parameters supplying - traits or policies to allow extensive user customization?- A. Parameterization discourages users. The
-shared_ptr
template is - carefully crafted to meet common needs without extensive parameterization. Some - day a highly configurable smart pointer may be invented that is also very easy - to use and very hard to misuse. Until then,shared_ptr
is the smart - pointer of choice for a wide range of applications. (Those interested in policy - based smart pointers should read - Modern C++ Design by Andrei Alexandrescu.) -Q. I am not convinced. Default parameters can be used where appropriate - to hide the complexity. Again, why not policies?
-- A. Template parameters affect the type. See the answer to the first - question above. -
-Q. Why doesn't
-shared_ptr
use a linked list implementation?- A. A linked list implementation does not offer enough advantages to - offset the added cost of an extra pointer. See timings - page. In addition, it is expensive to make a linked list implementation thread - safe. -
-Q. Why doesn't
-shared_ptr
(or any of the other Boost smart - pointers) supply an automatic conversion toT*
?- A. Automatic conversion is believed to be too error prone. -
-Q. Why does
-shared_ptr
supplyuse_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 - complex project that turned out to have cyclic-dependencies. -Q. Why doesn't
-shared_ptr
specify complexity requirements?- A. Because complexity requirements limit implementors and complicate the - specification without apparent benefit to
-shared_ptr
users. For example, - error-checking implementations might become non-conforming if they had to meet - stringent complexity requirements. -Q. Why doesn't
-shared_ptr
provide arelease()
function?- A.
-shared_ptr
cannot give away ownership unless it'sunique()
- because the other copy will still destroy the object.Consider:
-+shared_ptr<int> a(new int); ++
Starting with Boost release 1.33.0,
+shared_ptr
uses a lock-free + implementation on most common platforms.If your program is single-threaded and does not link to any libraries that might + have used
+shared_ptr
in its default configuration, you can+ #define
the macroBOOST_SP_DISABLE_THREADS
on a + project-wide basis to switch to ordinary non-atomic reference count updates.(Defining
+BOOST_SP_DISABLE_THREADS
in some, but not all, + translation units is technically a violation of the One Definition Rule and + undefined behavior. Nevertheless, the implementation attempts to do its best to + accommodate the request to use non-atomic updates in those translation units. + No guarantees, though.)You can define the macro
+BOOST_SP_USE_PTHREADS
to turn off the + lock-free platform-specific implementation and fall back to the generic +pthread_mutex_t
-based code.Frequently Asked Questions
+Q. There are several variations of shared pointers, with different + tradeoffs; why does the smart pointer library supply only a single + implementation? It would be useful to be able to experiment with each type so + as to find the most suitable for the job at hand?
++ A. An important goal of
+shared_ptr
is to provide a + standard shared-ownership pointer. Having a single pointer type is important + for stable library interfaces, since different shared pointers typically cannot + interoperate, i.e. a reference counted pointer (used by library A) cannot share + ownership with a linked pointer (used by library B.) +Q. Why doesn't
+shared_ptr
have template parameters supplying + traits or policies to allow extensive user customization?+ A. Parameterization discourages users. The
+shared_ptr
template is + carefully crafted to meet common needs without extensive parameterization. Some + day a highly configurable smart pointer may be invented that is also very easy + to use and very hard to misuse. Until then,shared_ptr
is the smart + pointer of choice for a wide range of applications. (Those interested in policy + based smart pointers should read + Modern C++ Design by Andrei Alexandrescu.) +Q. I am not convinced. Default parameters can be used where appropriate + to hide the complexity. Again, why not policies?
++ A. Template parameters affect the type. See the answer to the first + question above. +
+Q. Why doesn't
+shared_ptr
use a linked list implementation?+ A. A linked list implementation does not offer enough advantages to + offset the added cost of an extra pointer. See timings + page. In addition, it is expensive to make a linked list implementation thread + safe. +
+Q. Why doesn't
+shared_ptr
(or any of the other Boost smart + pointers) supply an automatic conversion toT*
?+ A. Automatic conversion is believed to be too error prone. +
+Q. Why does
+shared_ptr
supplyuse_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 + complex project that turned out to have cyclic-dependencies. +Q. Why doesn't
+shared_ptr
specify complexity requirements?+ A. Because complexity requirements limit implementors and complicate the + specification without apparent benefit to
+shared_ptr
users. For example, + error-checking implementations might become non-conforming if they had to meet + stringent complexity requirements. +Q. Why doesn't
+shared_ptr
provide arelease()
function?+ A.
+shared_ptr
cannot give away ownership unless it'sunique()
+ because the other copy will still destroy the object.Consider:
+-shared_ptr<int> a(new int); shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2 int * p = a.release(); // Who owns p now? b will still call delete on it in its destructor.-Furthermore, the pointer returned by
-release()
would be difficult - to deallocate reliably, as the sourceshared_ptr
could have been created - with a custom deleter. -Q. Why is
-operator->()
const, but its return value is a - non-const pointer to the element type?- A. Shallow copy pointers, including raw pointers, typically don't - propagate constness. It makes little sense for them to do so, as you can always - obtain a non-const pointer from a const one and then proceed to modify the - object through it.
-shared_ptr
is "as close to raw pointers as possible - but no closer". -
-Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - 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.
- +Furthermore, the pointer returned by
+release()
would be difficult + to deallocate reliably, as the sourceshared_ptr
could have been created + with a custom deleter. +Q. Why is
+operator->()
const, but its return value is a + non-const pointer to the element type?+ A. Shallow copy pointers, including raw pointers, typically don't + propagate constness. It makes little sense for them to do so, as you can always + obtain a non-const pointer from a const one and then proceed to modify the + object through it.
+shared_ptr
is "as close to raw pointers as possible + but no closer". +
+$Date$
+Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. + 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.
+ diff --git a/smart_ptr.htm b/smart_ptr.htm index 3956aaf..fab9dd6 100644 --- a/smart_ptr.htm +++ b/smart_ptr.htm @@ -1,216 +1,221 @@ - -Smart Pointers - - - --
Smart Pointers
Introduction
-
- Common Requirements
- Exception Safety
- Exception-specifications
- History and Acknowledgements
- ReferencesIntroduction
-Smart pointers are objects which store pointers to dynamically allocated (heap) - objects. They behave much like built-in C++ pointers except that they - automatically delete the object pointed to at the appropriate time. Smart - pointers are particularly useful in the face of exceptions as they ensure - proper destruction of dynamically allocated objects. They can also be used to - keep track of dynamically allocated objects shared by multiple owners.
-Conceptually, smart pointers are seen as owning the object pointed to, and thus - responsible for deletion of the object when it is no longer needed.
-The smart pointer library provides six smart pointer class templates:
----
-- -scoped_ptr -<boost/scoped_ptr.hpp> -Simple sole ownership of single objects. Noncopyable. -- -scoped_array -<boost/scoped_array.hpp> -Simple sole ownership of arrays. Noncopyable. -- -shared_ptr -<boost/shared_ptr.hpp> -Object ownership shared among multiple pointers. -- -shared_array -<boost/shared_array.hpp> -Array ownership shared among multiple pointers. -- -weak_ptr -<boost/weak_ptr.hpp> -Non-owning observers of an object owned by shared_ptr. -- -intrusive_ptr -<boost/intrusive_ptr.hpp> -Shared ownership of objects with an embedded reference count. -These templates are designed to complement the std::auto_ptr template.
-They are examples of the "resource acquisition is initialization" idiom - described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition, - Section 14.4, Resource Management.
-Additionally, the smart pointer library provides efficient factory functions - for creating smart pointer objects:
----
-- -make_shared and allocate_shared for objects -<boost/make_shared.hpp> -Efficient creation of -shared_ptr
objects.- -make_shared and allocate_shared for arrays -<boost/make_shared.hpp> -Efficient creation of -shared_ptr
arrays.- -make_unique -<boost/make_unique.hpp> -Creation of -unique_ptr
objects and arrays.A test program, smart_ptr_test.cpp, is - provided to verify correct operation.
-A page on compatibility with older versions of - the Boost smart pointer library describes some of the changes since earlier - versions of the smart pointer implementation.
-A page on smart pointer timings will be of interest - to those curious about performance issues.
-A page on smart pointer programming techniques lists - some advanced applications of
-shared_ptr
andweak_ptr
.Common Requirements
-These smart pointer class templates have a template parameter, T, which - specifies the type of the object pointed to by the smart pointer. The behavior - of the smart pointer templates is undefined if the destructor or operator delete - for objects of type T throw exceptions.
-T may be an incomplete type at the point of smart pointer declaration. - Unless otherwise specified, it is required that T be a complete type at - points of smart pointer instantiation. Implementations are required to diagnose - (treat as an error) all violations of this requirement, including deletion of - an incomplete type. See the description of the - checked_delete function template.
-Note that shared_ptr does not have this restriction, as most of - its member functions do not require T to be a complete type.
-Rationale
-The requirements on T are carefully crafted to maximize safety yet allow - handle-body (also called pimpl) and similar idioms. In these idioms a smart - pointer may appear in translation units where T is an incomplete type. - This separates interface from implementation and hides implementation from - translation units which merely use the interface. Examples described in the - documentation for specific smart pointers illustrate use of smart pointers in - these idioms.
-Note that scoped_ptr requires that T be a complete type at - destruction time, but shared_ptr does not.
-Exception Safety
-Several functions in these smart pointer classes are specified as having "no - effect" or "no effect except such-and-such" if an exception is thrown. This - means that when an exception is thrown by an object of one of these classes, - the entire program state remains the same as it was prior to the function call - which resulted in the exception being thrown. This amounts to a guarantee that - there are no detectable side effects. Other functions never throw exceptions. - The only exception ever thrown by functions which do throw (assuming T meets - the common requirements) is std::bad_alloc, - and that is thrown only by functions which are explicitly documented as - possibly throwing std::bad_alloc.
-Exception-specifications
-Exception-specifications are not used; see - exception-specification rationale.
-All the smart pointer templates contain member functions which can never throw - exceptions, because they neither throw exceptions themselves nor call other - functions which may throw exceptions. These members are indicated by a comment:
-- // never throws
. -Functions which destroy objects of the pointed to type are prohibited from - throwing exceptions by the common requirements.
-History and Acknowledgements
-January 2014. Glen Fernandes confined the overloads of make_shared - and allocate_shared for arrays to the specification in - N3870 - and implemented make_unique for arrays and objects.
-November 2012. Glen Fernandes provided implementations of make_shared - and allocate_shared for arrays. They achieve a single allocation for an - array that can be initialized with constructor arguments or initializer lists - as well as overloads for default initialization and no value initialization. - See the make_shared and allocate_shared for - arrays page for more information.
-January 2002. Peter Dimov reworked all four classes, adding features, fixing - bugs, and splitting them into four separate headers, and added weak_ptr. - See the compatibility page for a summary of the - changes.
-May 2001. Vladimir Prus suggested requiring a complete type on destruction. - Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman - Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and - others.
-November 1999. Darin Adler provided operator ==, operator !=, and std::swap - and std::less specializations for shared types.
-September 1999. Luis Coelho provided shared_ptr::swap and shared_array::swap
-May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a - number of suggestions resulting in numerous improvements.
-October 1998. Beman Dawes proposed reviving the original semantics under the - names safe_ptr and counted_ptr, meeting of Per Andersson, Matt - Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar Kühl, - Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new - class names were finalized, it was decided that there was no need to exactly - follow the std::auto_ptr interface, and various function signatures and - semantics were finalized.
-Over the next three months, several implementations were considered for shared_ptr, - and discussed on the boost.org mailing list. - The implementation questions revolved around the reference count which must be - kept, either attached to the pointed to object, or detached elsewhere. Each of - those variants have themselves two major variants: -
-
-- - Direct detached: the shared_ptr contains a pointer to the object, and a pointer - to the count. -
- - Indirect detached: the shared_ptr contains a pointer to a helper object, which - in turn contains a pointer to the object and the count. -
- - Embedded attached: the count is a member of the object pointed to. -
- - Placement attached: the count is attached via operator new manipulations.
-Each implementation technique has advantages and disadvantages. We went so far - as to run various timings of the direct and indirect approaches, and found that - at least on Intel Pentium chips there was very little measurable difference. - Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar - Kühl suggested an elegant partial template specialization technique to allow - users to choose which implementation they preferred, and that was also - experimented with.
-But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage - users", and in the end we choose to supply only the direct implementation.
-Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named auto_ptr - and counted_ptr which were very similar to what we now call scoped_ptr - and shared_ptr. [Col-94] In one of the very few - cases where the Library Working Group's recommendations were not followed by - the full committee, counted_ptr was rejected and surprising - transfer-of-ownership semantics were added to auto_ptr.
-References
-[Col-94] Gregory Colvin, - Exception Safe Smart Pointers, C++ committee document 94-168/N0555, - July, 1994.
-[E&D-94] John R. Ellis & David L. Detlefs, - Safe, Efficient Garbage Collection for C++, Usenix Proceedings, - February, 1994. This paper includes an extensive discussion of weak pointers - and an extensive bibliography.
-
-$Date$
-Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - 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.
- + +Smart Pointers + + + ++
Smart Pointers
Introduction
+
+ Common Requirements
+ Exception Safety
+ Exception-specifications
+ History and Acknowledgements
+ ReferencesIntroduction
+Smart pointers are objects which store pointers to dynamically allocated (heap) + objects. They behave much like built-in C++ pointers except that they + automatically delete the object pointed to at the appropriate time. Smart + pointers are particularly useful in the face of exceptions as they ensure + proper destruction of dynamically allocated objects. They can also be used to + keep track of dynamically allocated objects shared by multiple owners.
+Conceptually, smart pointers are seen as owning the object pointed to, and thus + responsible for deletion of the object when it is no longer needed.
+The smart pointer library provides six smart pointer class templates:
++++
++ +scoped_ptr +<boost/scoped_ptr.hpp> +Simple sole ownership of single objects. Noncopyable. ++ +scoped_array +<boost/scoped_array.hpp> +Simple sole ownership of arrays. Noncopyable. ++ +shared_ptr +<boost/shared_ptr.hpp> +Object ownership shared among multiple pointers. ++ +shared_array +<boost/shared_array.hpp> +Array ownership shared among multiple pointers. ++ +weak_ptr +<boost/weak_ptr.hpp> +Non-owning observers of an object owned by shared_ptr. ++ +intrusive_ptr +<boost/intrusive_ptr.hpp> +Shared ownership of objects with an embedded reference count. +These templates are designed to complement the std::auto_ptr template.
+They are examples of the "resource acquisition is initialization" idiom + described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition, + Section 14.4, Resource Management.
+Additionally, the smart pointer library provides efficient factory functions + for creating smart pointer objects:
++++
++ +make_shared, allocate_shared for objects +<boost/make_shared.hpp> +Efficient creation of +shared_ptr
objects.+ +make_shared, allocate_shared for arrays +<boost/make_shared.hpp> +Efficient creation of +shared_ptr
arrays.+ +make_unique +<boost/make_unique.hpp> +Creation of +unique_ptr
objects and arrays.A test program, smart_ptr_test.cpp, is + provided to verify correct operation.
+A page on compatibility with older versions of + the Boost smart pointer library describes some of the changes since earlier + versions of the smart pointer implementation.
+A page on smart pointer timings will be of interest + to those curious about performance issues.
+A page on smart pointer programming techniques lists + some advanced applications of
+shared_ptr
andweak_ptr
.Common Requirements
+These smart pointer class templates have a template parameter, T, which + specifies the type of the object pointed to by the smart pointer. The behavior + of the smart pointer templates is undefined if the destructor or operator delete + for objects of type T throw exceptions.
+T may be an incomplete type at the point of smart pointer declaration. + Unless otherwise specified, it is required that T be a complete type at + points of smart pointer instantiation. Implementations are required to diagnose + (treat as an error) all violations of this requirement, including deletion of + an incomplete type. See the description of the + checked_delete function template.
+Note that shared_ptr does not have this restriction, as most of + its member functions do not require T to be a complete type.
+Rationale
+The requirements on T are carefully crafted to maximize safety yet allow + handle-body (also called pimpl) and similar idioms. In these idioms a smart + pointer may appear in translation units where T is an incomplete type. + This separates interface from implementation and hides implementation from + translation units which merely use the interface. Examples described in the + documentation for specific smart pointers illustrate use of smart pointers in + these idioms.
+Note that scoped_ptr requires that T be a complete type at + destruction time, but shared_ptr does not.
+Exception Safety
+Several functions in these smart pointer classes are specified as having "no + effect" or "no effect except such-and-such" if an exception is thrown. This + means that when an exception is thrown by an object of one of these classes, + the entire program state remains the same as it was prior to the function call + which resulted in the exception being thrown. This amounts to a guarantee that + there are no detectable side effects. Other functions never throw exceptions. + The only exception ever thrown by functions which do throw (assuming T meets + the common requirements) is std::bad_alloc, + and that is thrown only by functions which are explicitly documented as + possibly throwing std::bad_alloc.
+Exception-specifications
+Exception-specifications are not used; see + exception-specification rationale.
+All the smart pointer templates contain member functions which can never throw + exceptions, because they neither throw exceptions themselves nor call other + functions which may throw exceptions. These members are indicated by a comment:
++ // never throws
. +Functions which destroy objects of the pointed to type are prohibited from + throwing exceptions by the common requirements.
+History and Acknowledgements
+February 2014. Glen Fernandes updated overloads of make_shared and + allocate_shared to conform to the specification in C++ standard paper + [D&F-14], and implemented make_unique for + arrays and objects. Peter Dimov and Glen Fernandes updated the scalar and + array implementations, respectively, to resolve C++ standard library defect + 2070.
+November 2012. Glen Fernandes provided implementations of make_shared + and allocate_shared for arrays. They achieve a single allocation for an + array that can be initialized with constructor arguments or initializer lists + as well as overloads for default initialization and no value initialization. + See the make_shared and allocate_shared for + arrays page for more information.
+January 2002. Peter Dimov reworked all four classes, adding features, fixing + bugs, and splitting them into four separate headers, and added weak_ptr. + See the compatibility page for a summary of the + changes.
+May 2001. Vladimir Prus suggested requiring a complete type on destruction. + Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman + Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and + others.
+November 1999. Darin Adler provided operator ==, operator !=, and std::swap + and std::less specializations for shared types.
+September 1999. Luis Coelho provided shared_ptr::swap and shared_array::swap
+May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a + number of suggestions resulting in numerous improvements.
+October 1998. Beman Dawes proposed reviving the original semantics under the + names safe_ptr and counted_ptr, meeting of Per Andersson, Matt + Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar Kühl, + Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new + class names were finalized, it was decided that there was no need to exactly + follow the std::auto_ptr interface, and various function signatures and + semantics were finalized.
+Over the next three months, several implementations were considered for shared_ptr, + and discussed on the boost.org mailing list. + The implementation questions revolved around the reference count which must be + kept, either attached to the pointed to object, or detached elsewhere. Each of + those variants have themselves two major variants: +
+
+- + Direct detached: the shared_ptr contains a pointer to the object, and a pointer + to the count. +
- + Indirect detached: the shared_ptr contains a pointer to a helper object, which + in turn contains a pointer to the object and the count. +
- + Embedded attached: the count is a member of the object pointed to. +
- + Placement attached: the count is attached via operator new manipulations.
+Each implementation technique has advantages and disadvantages. We went so far + as to run various timings of the direct and indirect approaches, and found that + at least on Intel Pentium chips there was very little measurable difference. + Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar + Kühl suggested an elegant partial template specialization technique to allow + users to choose which implementation they preferred, and that was also + experimented with.
+But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage + users", and in the end we choose to supply only the direct implementation.
+Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named auto_ptr + and counted_ptr which were very similar to what we now call scoped_ptr + and shared_ptr. [Col-94] In one of the very few + cases where the Library Working Group's recommendations were not followed by + the full committee, counted_ptr was rejected and surprising + transfer-of-ownership semantics were added to auto_ptr.
+References
+[D&F-14] Peter Dimov & Glen Fernandes, + Extending make_shared to Support Arrays, Revision 1, C++ committee document N3870, + January, 2014.
+[Col-94] Gregory Colvin, + Exception Safe Smart Pointers, C++ committee document 94-168/N0555, + July, 1994.
+[E&D-94] John R. Ellis & David L. Detlefs, + Safe, Efficient Garbage Collection for C++, Usenix Proceedings, + February, 1994. This paper includes an extensive discussion of weak pointers + and an extensive bibliography.
+
+$Date$
+Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. + 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/smarttests.htm b/smarttests.htm index 1833719..2551ae4 100644 --- a/smarttests.htm +++ b/smarttests.htm @@ -7,9 +7,9 @@ - - -+ + +
Smart Pointer Timings
Smart Pointer Timings
In late January 2000, Mark Borgerding put forward a suggestion to boost for a new design of smart pointer whereby an intrusive doubly linked list is used @@ -533,9 +533,8 @@ Gavin Collings, spreads its information as in the case of linked pointer.
-Revised 19 August 2001 -
-© Copyright Gavin Collings 2000. Permission to copy, use, modify, sell +
$Date$
+© Copyright Gavin Collings 2000. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.
diff --git a/sp_techniques.html b/sp_techniques.html index f869279..7e0ce8f 100644 --- a/sp_techniques.html +++ b/sp_techniques.html @@ -1,67 +1,67 @@ - + - -Smart Pointer Programming Techniques - - - --
Smart Pointer Programming Techniques
Using incomplete classes for implementation hiding
-
- The "Pimpl" idiom
- Using abstract classes for implementation hiding
- Preventingdelete px.get()
- Using ashared_ptr
to hold a pointer to an array
- Encapsulating allocation details, wrapping factory - functions
- Using ashared_ptr
to hold a pointer to a statically - allocated object
- Using ashared_ptr
to hold a pointer to a COM object
- Using ashared_ptr
to hold a pointer to an object - with an embedded reference count
- Using ashared_ptr
to hold another shared - ownership smart pointer
- Obtaining ashared_ptr
from a raw pointer
- Obtaining ashared_ptr
(weak_ptr
) - tothis
in a constructor
- Obtaining ashared_ptr
tothis
- Usingshared_ptr
as a smart counted handle
- Usingshared_ptr
to execute code on block - exit
- Usingshared_ptr<void>
to hold an arbitrary - object
- Associating arbitrary data with heterogeneousshared_ptr
- instances
- Usingshared_ptr
as a CopyConstructible mutex lock
- Usingshared_ptr
to wrap member function calls
- Delayed deallocation
- Weak pointers to objects not managed by ashared_ptr
-Using incomplete classes for implementation hiding
-A proven technique (that works in C, too) for separating interface from - implementation is to use a pointer to an incomplete class as an opaque handle:
-class FILE; + +Smart Pointer Programming Techniques + + + ++
Smart Pointer Programming Techniques
Using incomplete classes for implementation hiding
+
+ The "Pimpl" idiom
+ Using abstract classes for implementation hiding
+ Preventingdelete px.get()
+ Using ashared_ptr
to hold a pointer to an array
+ Encapsulating allocation details, wrapping factory + functions
+ Using ashared_ptr
to hold a pointer to a statically + allocated object
+ Using ashared_ptr
to hold a pointer to a COM object
+ Using ashared_ptr
to hold a pointer to an object + with an embedded reference count
+ Using ashared_ptr
to hold another shared + ownership smart pointer
+ Obtaining ashared_ptr
from a raw pointer
+ Obtaining ashared_ptr
(weak_ptr
) + tothis
in a constructor
+ Obtaining ashared_ptr
tothis
+ Usingshared_ptr
as a smart counted handle
+ Usingshared_ptr
to execute code on block + exit
+ Usingshared_ptr<void>
to hold an arbitrary + object
+ Associating arbitrary data with heterogeneousshared_ptr
+ instances
+ Usingshared_ptr
as a CopyConstructible mutex lock
+ Usingshared_ptr
to wrap member function calls
+ Delayed deallocation
+ Weak pointers to objects not managed by ashared_ptr
+Using incomplete classes for implementation hiding
+A proven technique (that works in C, too) for separating interface from + implementation is to use a pointer to an incomplete class as an opaque handle:
+class FILE; FILE * fopen(char const * name, char const * mode); void fread(FILE * f, void * data, size_t size); void fclose(FILE * f);-It is possible to express the above interface using
-shared_ptr
, - eliminating the need to manually callfclose
:class FILE; +It is possible to express the above interface using
+shared_ptr
, + eliminating the need to manually callfclose
:class FILE; shared_ptr<FILE> fopen(char const * name, char const * mode); void fread(shared_ptr<FILE> f, void * data, size_t size);-This technique relies on
-shared_ptr
's ability to execute a custom - deleter, eliminating the explicit call tofclose
, and on the fact - thatshared_ptr<X>
can be copied and destroyed whenX
- is incomplete.The "Pimpl" idiom
-A C++ specific variation of the incomplete class pattern is the "Pimpl" idiom. - The incomplete class is not exposed to the user; it is hidden behind a - forwarding facade.
-shared_ptr
can be used to implement a "Pimpl":// file.hpp: +This technique relies on
+shared_ptr
's ability to execute a custom + deleter, eliminating the explicit call tofclose
, and on the fact + thatshared_ptr<X>
can be copied and destroyed whenX
+ is incomplete.The "Pimpl" idiom
+A C++ specific variation of the incomplete class pattern is the "Pimpl" idiom. + The incomplete class is not exposed to the user; it is hidden behind a + forwarding facade.
+shared_ptr
can be used to implement a "Pimpl":// file.hpp: class file { @@ -79,7 +79,7 @@ public: void read(void * data, size_t size); };-// file.cpp: +// file.cpp: #include "file.hpp" @@ -108,17 +108,17 @@ void file::read(void * data, size_t size) pimpl_->read(data, size); }-The key thing to note here is that the compiler-generated copy constructor, - assignment operator, and destructor all have a sensible meaning. As a result,
-- file
isCopyConstructible
andAssignable
, - allowing its use in standard containers.Using abstract classes for implementation hiding
-Another widely used C++ idiom for separating inteface and implementation is to - use abstract base classes and factory functions. The abstract classes are - sometimes called "interfaces" and the pattern is known as "interface-based - programming". Again,
-shared_ptr
can be used as the return type of - the factory functions:// X.hpp: +The key thing to note here is that the compiler-generated copy constructor, + assignment operator, and destructor all have a sensible meaning. As a result,
++ file
isCopyConstructible
andAssignable
, + allowing its use in standard containers.Using abstract classes for implementation hiding
+Another widely used C++ idiom for separating inteface and implementation is to + use abstract base classes and factory functions. The abstract classes are + sometimes called "interfaces" and the pattern is known as "interface-based + programming". Again,
+shared_ptr
can be used as the return type of + the factory functions:// X.hpp: class X { @@ -134,7 +134,7 @@ protected: shared_ptr<X> createX();--- X.cpp: +-- X.cpp: class X_impl: public X { @@ -162,18 +162,18 @@ shared_ptr<X> createX() return px; }-A key property of shared_ptr is that the allocation, construction, deallocation, - and destruction details are captured at the point of construction, inside the - factory function. Note the protected and nonvirtual destructor in the example - above. The client code cannot, and does not need to, delete a pointer to
-X
; - theshared_ptr<X>
instance returned fromcreateX
- will correctly call~X_impl
.Preventing
-delete px.get()
It is often desirable to prevent client code from deleting a pointer that is - being managed by
-shared_ptr
. The previous technique showed one - possible approach, using a protected destructor. Another alternative is to use - a private deleter:class X +A key property of shared_ptr is that the allocation, construction, deallocation, + and destruction details are captured at the point of construction, inside the + factory function. Note the protected and nonvirtual destructor in the example + above. The client code cannot, and does not need to, delete a pointer to
+X
; + theshared_ptr<X>
instance returned fromcreateX
+ will correctly call~X_impl
.Preventing
+delete px.get()
It is often desirable to prevent client code from deleting a pointer that is + being managed by
+shared_ptr
. The previous technique showed one + possible approach, using a protected destructor. Another alternative is to use + a private deleter:class X { private: @@ -198,48 +198,48 @@ public: } };-Using a
-shared_ptr
to hold a pointer to an arrayA
-shared_ptr
can be used to hold a pointer to an array allocated - withnew[]
:shared_ptr<X> px(new X[1], checked_array_deleter<X>()); +Using a
+shared_ptr
to hold a pointer to an arrayA
+shared_ptr
can be used to hold a pointer to an array allocated + withnew[]
:shared_ptr<X> px(new X[1], checked_array_deleter<X>());-Note, however, that
-shared_array
is - often preferable, if this is an option. It has an array-specific interface, - withoutoperator*
andoperator->
, and does not - allow pointer conversions.Encapsulating allocation details, wrapping factory - functions
--
shared_ptr
can be used in creating C++ wrappers over existing C - style library interfaces that return raw pointers from their factory functions - to encapsulate allocation details. As an example, consider this interface, - whereCreateX
might allocateX
from its own private - heap,~X
may be inaccessible, orX
may be incomplete:X * CreateX(); +Note, however, that
+shared_array
is + often preferable, if this is an option. It has an array-specific interface, + withoutoperator*
andoperator->
, and does not + allow pointer conversions.Encapsulating allocation details, wrapping factory + functions
++
shared_ptr
can be used in creating C++ wrappers over existing C + style library interfaces that return raw pointers from their factory functions + to encapsulate allocation details. As an example, consider this interface, + whereCreateX
might allocateX
from its own private + heap,~X
may be inaccessible, orX
may be incomplete:X * CreateX(); void DestroyX(X *);-The only way to reliably destroy a pointer returned by
-CreateX
is - to callDestroyX
.Here is how a
-shared_ptr
-based wrapper may look like:shared_ptr<X> createX() +The only way to reliably destroy a pointer returned by
+CreateX
is + to callDestroyX
.Here is how a
+shared_ptr
-based wrapper may look like:shared_ptr<X> createX() { shared_ptr<X> px(CreateX(), DestroyX); return px; }-Client code that calls
-createX
still does not need to know how the - object has been allocated, but now the destruction is automatic.Using a
-shared_ptr
to hold a pointer to a statically - allocated objectSometimes it is desirable to create a
-shared_ptr
to an already - existing object, so that theshared_ptr
does not attempt to - destroy the object when there are no more references left. As an example, the - factory function:shared_ptr<X> createX(); +Client code that calls
+createX
still does not need to know how the + object has been allocated, but now the destruction is automatic.Using a
+shared_ptr
to hold a pointer to a statically + allocated objectSometimes it is desirable to create a
+shared_ptr
to an already + existing object, so that theshared_ptr
does not attempt to + destroy the object when there are no more references left. As an example, the + factory function:shared_ptr<X> createX();-in certain situations may need to return a pointer to a statically allocated
-X
- instance.The solution is to use a custom deleter that does nothing:
-struct null_deleter +in certain situations may need to return a pointer to a statically allocated
+X
+ instance.The solution is to use a custom deleter that does nothing:
+struct null_deleter { void operator()(void const *) const { @@ -254,33 +254,33 @@ shared_ptr<X> createX() return px; }-The same technique works for any object known to outlive the pointer.
-Using a
-shared_ptr
to hold a pointer to a COM ObjectBackground: COM objects have an embedded reference count and two member - functions that manipulate it.
-AddRef()
increments the count.Release()
- decrements the count and destroys itself when the count drops to zero.It is possible to hold a pointer to a COM object in a
-shared_ptr
:shared_ptr<IWhatever> make_shared_from_COM(IWhatever * p) +The same technique works for any object known to outlive the pointer.
+Using a
+shared_ptr
to hold a pointer to a COM ObjectBackground: COM objects have an embedded reference count and two member + functions that manipulate it.
+AddRef()
increments the count.Release()
+ decrements the count and destroys itself when the count drops to zero.It is possible to hold a pointer to a COM object in a
+shared_ptr
:shared_ptr<IWhatever> make_shared_from_COM(IWhatever * p) { p->AddRef(); shared_ptr<IWhatever> pw(p, mem_fn(&IWhatever::Release)); return pw; }-Note, however, that
-shared_ptr
copies created frompw
will - not "register" in the embedded count of the COM object; they will share the - single reference created inmake_shared_from_COM
. Weak pointers - created frompw
will be invalidated when the lastshared_ptr
- is destroyed, regardless of whether the COM object itself is still alive.As explained in the
-mem_fn
documentation, - you need to #define - BOOST_MEM_FN_ENABLE_STDCALL first.Using a
-shared_ptr
to hold a pointer to an object - with an embedded reference countThis is a generalization of the above technique. The example assumes that the - object implements the two functions required by
-intrusive_ptr
, -intrusive_ptr_add_ref
andintrusive_ptr_release
:template<class T> struct intrusive_deleter +Note, however, that
+shared_ptr
copies created frompw
will + not "register" in the embedded count of the COM object; they will share the + single reference created inmake_shared_from_COM
. Weak pointers + created frompw
will be invalidated when the lastshared_ptr
+ is destroyed, regardless of whether the COM object itself is still alive.As explained in the
+mem_fn
documentation, + you need to #define + BOOST_MEM_FN_ENABLE_STDCALL first.Using a
+shared_ptr
to hold a pointer to an object + with an embedded reference countThis is a generalization of the above technique. The example assumes that the + object implements the two functions required by
+intrusive_ptr
, +intrusive_ptr_add_ref
andintrusive_ptr_release
:template<class T> struct intrusive_deleter { void operator()(T * p) { @@ -295,15 +295,15 @@ shared_ptr<X> make_shared_from_intrusive(X * p) return px; }-Using a
-shared_ptr
to hold another shared - ownership smart pointerOne of the design goals of
-shared_ptr
is to be used in library - interfaces. It is possible to encounter a situation where a library takes ashared_ptr
- argument, but the object at hand is being managed by a different reference - counted or linked smart pointer.It is possible to exploit
-shared_ptr
's custom deleter feature to - wrap this existing smart pointer behind ashared_ptr
facade:template<class P> struct smart_pointer_deleter +Using a
+shared_ptr
to hold another shared + ownership smart pointerOne of the design goals of
+shared_ptr
is to be used in library + interfaces. It is possible to encounter a situation where a library takes ashared_ptr
+ argument, but the object at hand is being managed by a different reference + counted or linked smart pointer.It is possible to exploit
+shared_ptr
's custom deleter feature to + wrap this existing smart pointer behind ashared_ptr
facade:template<class P> struct smart_pointer_deleter { private: @@ -332,17 +332,17 @@ shared_ptr<X> make_shared_from_another(another_ptr<X> qx) return px; }-One subtle point is that deleters are not allowed to throw exceptions, and the - above example as written assumes that
-p_.reset()
doesn't throw. If - this is not the case,p_.reset()
should be wrapped in atry {} - catch(...) {}
block that ignores exceptions. In the (usually - unlikely) event when an exception is thrown and ignored,p_
will - be released when the lifetime of the deleter ends. This happens when all - references, including weak pointers, are destroyed or reset.Another twist is that it is possible, given the above
-shared_ptr
instance, - to recover the original smart pointer, using- get_deleter
:void extract_another_from_shared(shared_ptr<X> px) +One subtle point is that deleters are not allowed to throw exceptions, and the + above example as written assumes that
+p_.reset()
doesn't throw. If + this is not the case,p_.reset()
should be wrapped in atry {} + catch(...) {}
block that ignores exceptions. In the (usually + unlikely) event when an exception is thrown and ignored,p_
will + be released when the lifetime of the deleter ends. This happens when all + references, including weak pointers, are destroyed or reset.Another twist is that it is possible, given the above
+shared_ptr
instance, + to recover the original smart pointer, using+ get_deleter
:void extract_another_from_shared(shared_ptr<X> px) { typedef smart_pointer_deleter< another_ptr<X> > deleter; @@ -356,37 +356,37 @@ shared_ptr<X> make_shared_from_another(another_ptr<X> qx) } }-Obtaining a
-shared_ptr
from a raw pointerSometimes it is necessary to obtain a
-shared_ptr
given a raw - pointer to an object that is already managed by anothershared_ptr
- instance. Example:void f(X * p) +Obtaining a
+shared_ptr
from a raw pointerSometimes it is necessary to obtain a
+shared_ptr
given a raw + pointer to an object that is already managed by anothershared_ptr
+ instance. Example:void f(X * p) { shared_ptr<X> px(???); }-Inside
-f
, we'd like to create ashared_ptr
to*p
.In the general case, this problem has no solution. One approach is to modify
-f
- to take ashared_ptr
, if possible:void f(shared_ptr<X> px); +Inside
+f
, we'd like to create ashared_ptr
to*p
.In the general case, this problem has no solution. One approach is to modify
+f
+ to take ashared_ptr
, if possible:void f(shared_ptr<X> px);-The same transformation can be used for nonvirtual member functions, to convert - the implicit
-this
:void X::f(int m); +The same transformation can be used for nonvirtual member functions, to convert + the implicit
+this
:void X::f(int m);-would become a free function with a
-shared_ptr
first argument:void f(shared_ptr<X> this_, int m); +would become a free function with a
+shared_ptr
first argument:void f(shared_ptr<X> this_, int m);-If
-f
cannot be changed, butX
uses intrusive counting, - usemake_shared_from_intrusive
described - above. Or, if it's known that theshared_ptr
created inf
- will never outlive the object, use a null deleter.Obtaining a
-shared_ptr
(weak_ptr
) - tothis
in a constructorSome designs require objects to register themselves on construction with a - central authority. When the registration routines take a shared_ptr, this leads - to the question how could a constructor obtain a shared_ptr to this:
-class X +If
+f
cannot be changed, butX
uses intrusive counting, + usemake_shared_from_intrusive
described + above. Or, if it's known that theshared_ptr
created inf
+ will never outlive the object, use a null deleter.Obtaining a
+shared_ptr
(weak_ptr
) + tothis
in a constructorSome designs require objects to register themselves on construction with a + central authority. When the registration routines take a shared_ptr, this leads + to the question how could a constructor obtain a shared_ptr to this:
+class X { public: @@ -396,19 +396,19 @@ public: } };-In the general case, the problem cannot be solved. The
-X
instance - being constructed can be an automatic variable or a static variable; it can be - created on the heap:shared_ptr<X> px(new X);-but at construction time,
-px
does not exist yet, and it is - impossible to create anothershared_ptr
instance that shares - ownership with it.Depending on context, if the inner
-shared_ptr
this_
doesn't - need to keep the object alive, use anull_deleter
as explained - here and here. IfX
is - supposed to always live on the heap, and be managed by ashared_ptr
, - use a static factory function:class X +In the general case, the problem cannot be solved. The
+X
instance + being constructed can be an automatic variable or a static variable; it can be + created on the heap:shared_ptr<X> px(new X);+but at construction time,
+px
does not exist yet, and it is + impossible to create anothershared_ptr
instance that shares + ownership with it.Depending on context, if the inner
+shared_ptr
this_
doesn't + need to keep the object alive, use anull_deleter
as explained + here and here. IfX
is + supposed to always live on the heap, and be managed by ashared_ptr
, + use a static factory function:class X { private: @@ -424,13 +424,13 @@ public: } };-Obtaining a
-shared_ptr
tothis
Sometimes it is needed to obtain a
-shared_ptr
fromthis
- in a virtual member function under the assumption thatthis
is - already managed by ashared_ptr
. The transformations - described in the previous technique cannot be applied.A typical example:
-class X +Obtaining a
+shared_ptr
tothis
Sometimes it is needed to obtain a
+shared_ptr
fromthis
+ in a virtual member function under the assumption thatthis
is + already managed by ashared_ptr
. The transformations + described in the previous technique cannot be applied.A typical example:
+class X { public: @@ -469,8 +469,8 @@ public: } };-The solution is to keep a weak pointer to
-this
as a member inimpl
:class impl: public X, public Y +The solution is to keep a weak pointer to
+this
as a member inimpl
:class impl: public X, public Y { private: @@ -499,10 +499,10 @@ public: } };-The library now includes a helper class template
-- enable_shared_from_this
that can be used to encapsulate the - solution:class impl: public X, public Y, public enable_shared_from_this<impl> +The library now includes a helper class template
++ enable_shared_from_this
that can be used to encapsulate the + solution:class impl: public X, public Y, public enable_shared_from_this<impl> { public: @@ -519,19 +519,19 @@ public: } }-Note that you no longer need to manually initialize the
-weak_ptr
member - inenable_shared_from_this
. - Constructing ashared_ptr
toimpl
takes care of that.Using
-shared_ptr
as a smart counted handleSome library interfaces use opaque handles, a variation of the - incomplete class technique described above. An example:
-typedef void * HANDLE; +Note that you no longer need to manually initialize the
+weak_ptr
member + inenable_shared_from_this
. + Constructing ashared_ptr
toimpl
takes care of that.Using
+shared_ptr
as a smart counted handleSome library interfaces use opaque handles, a variation of the + incomplete class technique described above. An example:
+typedef void * HANDLE; HANDLE CreateProcess(); void CloseHandle(HANDLE);-Instead of a raw pointer, it is possible to use
-shared_ptr
as the - handle and get reference counting and automatic resource management for free:typedef shared_ptr<void> handle; +Instead of a raw pointer, it is possible to use
+shared_ptr
as the + handle and get reference counting and automatic resource management for free:typedef shared_ptr<void> handle; handle createProcess() { @@ -539,42 +539,42 @@ handle createProcess() return pv; }-Using
-shared_ptr
to execute code on block exit-
shared_ptr<void>
can automatically execute cleanup code when - control leaves a scope.-
-- - Executing
f(p)
, wherep
is a pointer:shared_ptr<void> guard(p, f); +Using
+shared_ptr
to execute code on block exit+
shared_ptr<void>
can automatically execute cleanup code when + control leaves a scope.+
+- + Executing
f(p)
, wherep
is a pointer:shared_ptr<void> guard(p, f);--
-- - Executing arbitrary code:
f(x, y)
:shared_ptr<void> guard(static_cast<void*>(0), bind(f, x, y)); ++
+- + Executing arbitrary code:
f(x, y)
:shared_ptr<void> guard(static_cast<void*>(0), bind(f, x, y));-For a more thorough treatment, see the article "Simplify Your Exception-Safe - Code" by Andrei Alexandrescu and Petru Marginean, available online at - http://www.cuj.com/experts/1812/alexandr.htm?topic=experts.
-Using
-shared_ptr<void>
to hold an arbitrary - object-
shared_ptr<void>
can act as a generic object pointer similar - tovoid*
. When ashared_ptr<void>
instance - constructed as:shared_ptr<void> pv(new X); +For a more thorough treatment, see the article "Simplify Your Exception-Safe + Code" by Andrei Alexandrescu and Petru Marginean, available online at + http://www.cuj.com/experts/1812/alexandr.htm?topic=experts.
+Using
+shared_ptr<void>
to hold an arbitrary + object+
shared_ptr<void>
can act as a generic object pointer similar + tovoid*
. When ashared_ptr<void>
instance + constructed as:shared_ptr<void> pv(new X);-is destroyed, it will correctly dispose of the
-X
object by - executing~X
.This propery can be used in much the same manner as a raw
-void*
is - used to temporarily strip type information from an object pointer. Ashared_ptr<void>
- can later be cast back to the correct type by using- static_pointer_cast
.Associating arbitrary data with heterogeneous
-shared_ptr
- instances-
shared_ptr
andweak_ptr
supportoperator<
- comparisons required by standard associative containers such asstd::map
. - This can be used to non-intrusively associate arbitrary data with objects - managed byshared_ptr
:typedef int Data; +is destroyed, it will correctly dispose of the
+X
object by + executing~X
.This propery can be used in much the same manner as a raw
+void*
is + used to temporarily strip type information from an object pointer. Ashared_ptr<void>
+ can later be cast back to the correct type by using+ static_pointer_cast
.Associating arbitrary data with heterogeneous
+shared_ptr
+ instances+
shared_ptr
andweak_ptr
supportoperator<
+ comparisons required by standard associative containers such asstd::map
. + This can be used to non-intrusively associate arbitrary data with objects + managed byshared_ptr
:typedef int Data; std::map< shared_ptr<void>, Data > userData; // or std::map< weak_ptr<void>, Data > userData; to not affect the lifetime @@ -585,11 +585,11 @@ shared_ptr<int> pi(new int(3)); userData[px] = 42; userData[pi] = 91;-Using
-shared_ptr
as a CopyConstructible mutex lockSometimes it's necessary to return a mutex lock from a function, and a - noncopyable lock cannot be returned by value. It is possible to use
-shared_ptr
- as a mutex lock:class mutex +Using
+shared_ptr
as a CopyConstructible mutex lockSometimes it's necessary to return a mutex lock from a function, and a + noncopyable lock cannot be returned by value. It is possible to use
+shared_ptr
+ as a mutex lock:class mutex { public: @@ -603,9 +603,9 @@ shared_ptr<mutex> lock(mutex & m) return shared_ptr<mutex>(&m, mem_fn(&mutex::unlock)); }-Better yet, the
-shared_ptr
instance acting as a lock can be - encapsulated in a dedicatedshared_lock
class:class shared_lock +Better yet, the
+shared_ptr
instance acting as a lock can be + encapsulated in a dedicatedshared_lock
class:class shared_lock { private: @@ -616,17 +616,17 @@ public: template<class Mutex> explicit shared_lock(Mutex & m): pv((m.lock(), &m), mem_fn(&Mutex::unlock)) {} };--
shared_lock
can now be used as:shared_lock lock(m); ++
shared_lock
can now be used as:shared_lock lock(m);-Note that
-shared_lock
is not templated on the mutex type, thanks to- shared_ptr<void>
's ability to hide type information.Using
-shared_ptr
to wrap member function calls-
shared_ptr
implements the ownership semantics required from theWrap
/CallProxy
- scheme described in Bjarne Stroustrup's article "Wrapping C++ Member Function - Calls" (available online at http://www.stroustrup.com/wrapper.pdf). - An implementation is given below:template<class T> class pointer +Note that
+shared_lock
is not templated on the mutex type, thanks to+ shared_ptr<void>
's ability to hide type information.Using
+shared_ptr
to wrap member function calls+
shared_ptr
implements the ownership semantics required from theWrap
/CallProxy
+ scheme described in Bjarne Stroustrup's article "Wrapping C++ Member Function + Calls" (available online at http://www.stroustrup.com/wrapper.pdf). + An implementation is given below:template<class T> class pointer { private: @@ -669,10 +669,10 @@ int main() px->g(); }-Delayed deallocation
-In some situations, a single
-px.reset()
can trigger an expensive - deallocation in a performance-critical region:class X; // ~X is expensive +Delayed deallocation
+In some situations, a single
+px.reset()
can trigger an expensive + deallocation in a performance-critical region:class X; // ~X is expensive class Y { @@ -686,10 +686,10 @@ public: } };-The solution is to postpone the potential deallocation by moving
-px
- to a dedicated free list that can be periodically emptied when performance and - response times are not an issue:vector< shared_ptr<void> > free_list; +The solution is to postpone the potential deallocation by moving
+px
+ to a dedicated free list that can be periodically emptied when performance and + response times are not an issue:vector< shared_ptr<void> > free_list; class Y { @@ -706,9 +706,9 @@ public: // periodically invoke free_list.clear() when convenient-Another variation is to move the free list logic to the construction point by - using a delayed deleter:
-struct delayed_deleter +Another variation is to move the free list logic to the construction point by + using a delayed deleter:
+struct delayed_deleter { template<class T> void operator()(T * p) { @@ -723,9 +723,9 @@ public: } };-Weak pointers to objects not managed by a
-shared_ptr
Make the object hold a
-shared_ptr
to itself, using anull_deleter
:class X +Weak pointers to objects not managed by a
+shared_ptr
Make the object hold a
+shared_ptr
to itself, using anull_deleter
:class X { private: @@ -748,18 +748,18 @@ public: X & operator=(X const & rhs) { - i_ = rhs.i_; + i_ = rhs.i_; } weak_ptr<X> get_weak_ptr() const { return this_; } };-When the object's lifetime ends,
-X::this_
will be destroyed, and - all weak pointers will automatically expire.
-$Date$
-Copyright © 2003 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.
- +When the object's lifetime ends,
+X::this_
will be destroyed, and + all weak pointers will automatically expire.
+$Date$
+Copyright © 2003 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/weak_ptr.htm b/weak_ptr.htm index 0fa87f7..4c256b8 100644 --- a/weak_ptr.htm +++ b/weak_ptr.htm @@ -1,42 +1,42 @@ - + - -weak_ptr - - - --
weak_ptr class template
Introduction
-
- Synopsis
- Members
- Free Functions
- Frequently Asked Questions -Introduction
-The weak_ptr class template stores a "weak reference" to an object that's - already managed by a shared_ptr. To access the object, a weak_ptr - can be converted to a shared_ptr using - the shared_ptr constructor or the member function - lock. When the last shared_ptr to the object goes - away and the object is deleted, the attempt to obtain a shared_ptr - from the weak_ptr instances that refer to the deleted object will fail: - the constructor will throw an exception of type boost::bad_weak_ptr, - and weak_ptr::lock will return an empty shared_ptr.
-Every weak_ptr meets the CopyConstructible and Assignable requirements - of the C++ Standard Library, and so can be used in standard library containers. - Comparison operators are supplied so that weak_ptr works with the - standard library's associative containers.
-weak_ptr operations never throw exceptions.
-The class template is parameterized on T, the type of the object pointed - to.
-Compared to shared_ptr, weak_ptr provides a - very limited subset of operations since accessing its stored pointer is often - dangerous in multithreaded programs, and sometimes unsafe even within a single - thread (that is, it may invoke undefined behavior.) Pretend for a moment that weak_ptr - has a get member function that returns a raw pointer, and consider this - innocent piece of code:
-shared_ptr<int> p(new int(5)); + +weak_ptr + + + ++
weak_ptr class template
Introduction
+
+ Synopsis
+ Members
+ Free Functions
+ Frequently Asked Questions +Introduction
+The weak_ptr class template stores a "weak reference" to an object that's + already managed by a shared_ptr. To access the object, a weak_ptr + can be converted to a shared_ptr using + the shared_ptr constructor or the member function + lock. When the last shared_ptr to the object goes + away and the object is deleted, the attempt to obtain a shared_ptr + from the weak_ptr instances that refer to the deleted object will fail: + the constructor will throw an exception of type boost::bad_weak_ptr, + and weak_ptr::lock will return an empty shared_ptr.
+Every weak_ptr meets the CopyConstructible and Assignable requirements + of the C++ Standard Library, and so can be used in standard library containers. + Comparison operators are supplied so that weak_ptr works with the + standard library's associative containers.
+weak_ptr operations never throw exceptions.
+The class template is parameterized on T, the type of the object pointed + to.
+Compared to shared_ptr, weak_ptr provides a + very limited subset of operations since accessing its stored pointer is often + dangerous in multithreaded programs, and sometimes unsafe even within a single + thread (that is, it may invoke undefined behavior.) Pretend for a moment that weak_ptr + has a get member function that returns a raw pointer, and consider this + innocent piece of code:
+shared_ptr<int> p(new int(5)); weak_ptr<int> q(p); // some time later @@ -46,12 +46,12 @@ 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)); +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 @@ -61,13 +61,13 @@ if(shared_ptr<int> r = q.lock()) // 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. By obtaining - a shared_ptr to the object, we have effectively locked it - against destruction.Synopsis
-namespace boost { +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. By obtaining + a shared_ptr to the object, we have effectively locked it + against destruction.Synopsis
+namespace boost { template<class T> class weak_ptr { @@ -101,119 +101,119 @@ if(shared_ptr<int> r = q.lock()) void swap(weak_ptr<T> & a, weak_ptr<T> & b); }-Members
-element_type
-typedef T element_type;---Provides the type of the template parameter T.
-constructors
-weak_ptr();---Effects: Constructs an empty weak_ptr.
-Postconditions:
-use_count() == 0
.Throws: nothing.
-template<class Y> weak_ptr(shared_ptr<Y> const & r); +Members
+element_type
+typedef T element_type;+++Provides the type of the template parameter T.
+constructors
+weak_ptr();+++Effects: Constructs an empty weak_ptr.
+Postconditions:
+use_count() == 0
.Throws: nothing.
+template<class Y> weak_ptr(shared_ptr<Y> const & r); weak_ptr(weak_ptr const & r); template<class Y> weak_ptr(weak_ptr<Y> const & r);---Effects: If r is empty, constructs an empty - weak_ptr; otherwise, constructs a weak_ptr that shares - ownership with r as if by storing a copy of the - pointer stored in r.
-Postconditions:
-use_count() == r.use_count()
.Throws: nothing.
-destructor
-~weak_ptr();---Effects: Destroys this weak_ptr but has no effect on the object - its stored pointer points to.
-Throws: nothing.
-assignment
-weak_ptr & operator=(weak_ptr const & r); +++Effects: If r is empty, constructs an empty + weak_ptr; otherwise, constructs a weak_ptr that shares + ownership with r as if by storing a copy of the + pointer stored in r.
+Postconditions:
+use_count() == r.use_count()
.Throws: nothing.
+destructor
+~weak_ptr();+++Effects: Destroys this weak_ptr but has no effect on the object + its stored pointer points to.
+Throws: nothing.
+assignment
+weak_ptr & operator=(weak_ptr const & r); template<class Y> weak_ptr & operator=(weak_ptr<Y> const & r); template<class Y> weak_ptr & operator=(shared_ptr<Y> const & r);---Effects: Equivalent to
-weak_ptr(r).swap(*this)
.Throws: nothing.
-Notes: The implementation is free to meet the effects (and the implied - guarantees) via different means, without creating a temporary.
-use_count
-long use_count() const;---Returns: 0 if *this is empty; otherwise, the - number of shared_ptr objects that share ownership with *this.
-Throws: nothing.
-Notes:
-use_count()
is not necessarily efficient. Use only - for debugging and testing purposes, not for production code.expired
-bool expired() const;---Returns:
-use_count() == 0
.Throws: nothing.
-Notes:
-expired()
may be faster thanuse_count()
.lock
-shared_ptr<T> lock() const;---Returns:
-expired()? shared_ptr<T>(): shared_ptr<T>(*this)
.Throws: nothing.
-reset
-void reset();---Effects: Equivalent to
-weak_ptr().swap(*this)
.swap
-void swap(weak_ptr & b);---Effects: Exchanges the contents of the two smart pointers.
-Throws: nothing.
-Free Functions
-comparison
-template<class T, class U> +++Effects: Equivalent to
+weak_ptr(r).swap(*this)
.Throws: nothing.
+Notes: The implementation is free to meet the effects (and the implied + guarantees) via different means, without creating a temporary.
+use_count
+long use_count() const;+++Returns: 0 if *this is empty; otherwise, the + number of shared_ptr objects that share ownership with *this.
+Throws: nothing.
+Notes:
+use_count()
is not necessarily efficient. Use only + for debugging and testing purposes, not for production code.expired
+bool expired() const;+++Returns:
+use_count() == 0
.Throws: nothing.
+Notes:
+expired()
may be faster thanuse_count()
.lock
+shared_ptr<T> lock() const;+++Returns:
+expired()? shared_ptr<T>(): shared_ptr<T>(*this)
.Throws: nothing.
+reset
+void reset();+++Effects: Equivalent to
+weak_ptr().swap(*this)
.swap
+void swap(weak_ptr & b);+++Effects: Exchanges the contents of the two smart pointers.
+Throws: nothing.
+Free Functions
+comparison
+template<class T, class U> bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b);---Returns: an unspecified value such that
--
-- - operator< is a strict weak ordering as described in section 25.3
[lib.alg.sorting]
- of the C++ standard; -- - under the equivalence relation defined by operator<,
!(a - < b) && !(b < a)
, two weak_ptr instances - are equivalent if and only if they share ownership or are both empty.Throws: nothing.
-Notes: Allows weak_ptr objects to be used as keys in - associative containers.
-swap
-template<class T> +++Returns: an unspecified value such that
++
+- + operator< is a strict weak ordering as described in section 25.3
[lib.alg.sorting]
+ of the C++ standard; +- + under the equivalence relation defined by operator<,
!(a + < b) && !(b < a)
, two weak_ptr instances + are equivalent if and only if they share ownership or are both empty.Throws: nothing.
+Notes: Allows weak_ptr objects to be used as keys in + associative containers.
+swap
+template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)---Effects: Equivalent to
-a.swap(b)
.Throws: nothing.
-Notes: Matches the interface of std::swap. Provided as an aid to - generic programming.
-Frequently Asked Questions
-Q. Can an object create a weak_ptr to itself in its - constructor?
-A. No. A weak_ptr can only be created from a shared_ptr, - and at object construction time no shared_ptr to the object - exists yet. Even if you could create a temporary shared_ptr to - this, it would go out of scope at the end of the constructor, and - all weak_ptr instances would instantly expire.
-The solution is to make the constructor private, and supply a factory function - that returns a shared_ptr:
-
-+++Effects: Equivalent to
+a.swap(b)
.Throws: nothing.
+Notes: Matches the interface of std::swap. Provided as an aid to + generic programming.
+Frequently Asked Questions
+Q. Can an object create a weak_ptr to itself in its + constructor?
+A. No. A weak_ptr can only be created from a shared_ptr, + and at object construction time no shared_ptr to the object + exists yet. Even if you could create a temporary shared_ptr to + this, it would go out of scope at the end of the constructor, and + all weak_ptr instances would instantly expire.
+The solution is to make the constructor private, and supply a factory function + that returns a shared_ptr:
+
+class X { private: @@ -230,13 +230,11 @@ public: } };--
-
-$Date$
-Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - Copyright 2002-2005 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.
- +
+$Date$
+Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. + Copyright 2002-2005 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.
+