Introduction

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. As such, 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.

This library provides six smart pointer class templates:

scoped_ptr, used to contain ownership of a dynamically allocated object to the current scope;

scoped_array, which provides scoped ownership for a dynamically allocated array;

shared_ptr, a versatile tool for managing shared ownership of an object or array;

weak_ptr, a non-owning observer to a shared_ptr-managed object that can be promoted temporarily to shared_ptr;

atomic_shared_ptr, a helper class implementing the interface of std::atomic for a value of type shared_ptr.

As a general rule, the destructor or operator delete for an object managed by pointers in the library
are not allowed to throw exceptions.

scoped_ptr: Scoped Object Ownership

Description

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.

scoped_ptr 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
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 or std::unique_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. Destroying T must not thow exceptions,
and T must be complete at the point scoped_ptr<T>::~scoped_ptr is instantiated.

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 std::auto_ptr or std::unique_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.

Frequently Asked Questions

Why doesn’t scoped_ptr have a release() member?

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)

scoped_array: Scoped Array Ownership

Description

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_ptr<T[]> 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_ptr<T[]> if scoped_array
does not meet your needs.

It cannot correctly hold a pointer to a single object. See scoped_ptr for that usage.

std::vector is an alternative to scoped_array that is a bit heavier duty but far more flexible.
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.

Members

element_type

constructors

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.

destructor

~scoped_array() noexcept;

Deletes the array pointed to by the stored pointer. Note that delete[] on a pointer with
a value of 0 is harmless. T must be complete, and delete[] on the stored pointer must
not throw exceptions.

reset

void reset(T * p = 0) noexcept;

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. T must be complete,
and delete[] on the stored pointer must not throw exceptions.

subscripting

T & operator[](std::ptrdiff_t i) const noexcept;

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 noexcept;

Returns the stored pointer. T need not be a complete type.

conversions

explicit operator bool () const noexcept;

Returns get() != 0.

Note

On C++03 compilers, the return value is of an unspecified type.

swap

void swap(scoped_array & b) noexcept;

Exchanges the contents of the two smart pointers. T need not be a complete type.

shared_ptr: Shared Ownership

Description

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 last shared_ptr pointing to it is destroyed or reset.

Code Example 1. Using shared_ptr

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, when p2 is destroyed or reset, it will call delete on the original
int* that has been passed to the constructor, even though p2 itself is of type shared_ptr<void> and stores a pointer of
type void*.

Every shared_ptr meets the CopyConstructible, MoveConstructible, CopyAssignable and MoveAssignable requirements of the
C++ Standard Library, and can be used in standard library containers. Comparison operators are supplied so that shared_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, if main()
holds a shared_ptr to A, which directly or indirectly holds a shared_ptr back to A, A’s use count will be 2. Destruction
of the original `shared_ptr will leave A dangling with a use count of 1. 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 on T; it is allowed to be an incomplete type, or void. Member functions that do place additional requirements
(constructors, reset) are explicitly documented below.

shared_ptr<T> can be implicitly converted to shared_ptr<U> whenever T* can be implicitly converted to U*. In particular,
shared_ptr<T> is implicitly convertible to shared_ptr<T const>, to shared_ptr<U> where U is an accessible base of T,
and to shared_ptr<void>.

shared_ptr is now part of the C++11 Standard, as std::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[] or T[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 enables operator[] to perform a range check on the index.

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 the new 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; having T and Y be the same type, or passing
arguments to the constructor of Y 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:

The function ok follows the guideline to the letter, whereas bad constructs the temporary shared_ptr in place, admitting the possibility of
a memory leak. Since function arguments are evaluated in unspecified order, it is possible for new int(2) to be evaluated first, g() second,
and we may never get to the shared_ptr constructor if g throws an exception. See Herb Sutter’s treatment of
the issue for more information.

The exception safety problem described above may also be eliminated by using the make_shared or allocate_shared factory
functions defined in <boost/smart_ptr/make_shared.hpp>. These factory functions also provide an efficiency benefit by consolidating allocations.

Members

element_type

element_type is T when T is not an array type, and U when T is U[] or U[N].

default constructor

constexpr shared_ptr() noexcept;

constexpr shared_ptr(std::nullptr_t) noexcept;

Effects

Constructs an empty shared_ptr.

Postconditions

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

pointer constructor

template<class Y> explicit shared_ptr(Y * p);

Requires

Y must be a complete type. The expression delete[] p, when T is an array type, or delete p, when T is not an array type,
must be well-formed, well-defined, and not throw exceptions. When T is U[N], Y(*)[N] must be convertible to T*; when T is U[], Y(*)[]
must be convertible to T*; otherwise, Y* must be convertible to T*.

Effects

When T is not an array type, constructs a shared_ptr that owns the pointer p. Otherwise, constructs a shared_ptr that owns p and
a deleter of an unspecified type that calls delete[] p.

Postconditions

use_count() == 1 && get() == p. If T is not an array type and p is unambiguously convertible to enable_shared_from_this<V>*
for some V, 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, when T is an array type, or delete p, when T is not an array type.

Note

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 if p
is 0; invoking delete on a pointer that has a value of 0 is harmless.

Note

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 when T does not have a virtual destructor, or is void.

constructors taking a deleter

template<class Y, class D> shared_ptr(Y * p, D d);

template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);

template<class D> shared_ptr(std::nullptr_t p, D d);

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

Requires

D must be CopyConstructible. The copy constructor and destructor of D must not throw. The expression d(p) must be well-formed, well-defined,
and not throw exceptions. A must be an Allocator, as described in section Allocator Requirements [allocator.requirements] of the C++ Standard.
When T is U[N], Y(*)[N] must be convertible to T*; when T is U[], Y(*)[] must be convertible to T*; otherwise, Y* must be convertible to T*.

Effects

Constructs a shared_ptr that owns the pointer p and the deleter d. The constructors taking an allocator a allocate memory using a copy of a.

Postconditions

use_count() == 1 && get() == p. If T is not an array type and p is unambiguously convertible to enable_shared_from_this<V>* for some V,
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.

Note

When the the time comes to delete the object pointed to by p, the stored copy of d is invoked with the stored copy of p as an argument.

Note

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 a shared_ptr to a statically allocated object, and other variations allow a shared_ptr to be used as a wrapper
for another smart pointer, easing interoperability.

Note

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) noexcept;

template<class Y> shared_ptr(shared_ptr<Y> const & r) noexcept;

Requires

Y* should be convertible to T*.

Effects

If r is empty, constructs an empty shared_ptr; otherwise, constructs a shared_ptr that shares ownership with r.

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.

get_deleter

Atomic Access

Note

The function in this section are atomic with respect to the first shared_ptr argument,
identified by *p. Concurrent access to the same shared_ptr instance is not a data race, if
done exclusively by the functions in this section.

If *p is equivalent to *v, assigns w to *p, otherwise assigns *p to *v.

Returns

true if *p was equivalent to *v, false otherwise.

Remarks

Two shared_ptr instances are equivalent if they store the same pointer value and share ownership.

Example

See shared_ptr_example.cpp for a complete example program. The program builds a
std::vector and std::set of shared_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 a std::set rather than a std::multiset, and thus does not contain duplicate entries.
Furthermore, the use count may be even higher at various times while push_back and insert 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 that T be a complete type.

Thread Safety

shared_ptr objects offer the same level of thread safety as built-in types. A shared_ptr instance can be "read" (accessed using only const operations)
simultaneously by multiple threads. Different shared_ptr instances can be "written to" (accessed using mutable operations such as operator= or reset)
simultaneously by multiple threads (even when these instances are copies, and share the same reference count underneath.)

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 macro BOOST_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

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?

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.)

Parameterization discourages users. The shared_ptr template is carefully crafted to meet common needs without extensive parameterization.

I am not convinced. Default parameters can be used where appropriate to hide the complexity. Again, why not policies?

Template parameters affect the type. See the answer to the first question above.

Why doesn’t shared_ptr use a linked list implementation?

A linked list implementation does not offer enough advantages to offset the added cost of an extra pointer. In addition, it is expensive to
make a linked list implementation thread safe.

Why doesn’t shared_ptr (or any of the other Boost smart pointers) supply an automatic conversion to T*?

Automatic conversion is believed to be too error prone.

Why does shared_ptr supply use_count()?

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.

Why doesn’t shared_ptr specify complexity requirements?

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.

Why doesn’t shared_ptr provide a release() function?

shared_ptr cannot give away ownership unless it’s unique() because the other copy will still destroy the object.

Furthermore, the pointer returned by release() would be difficult to deallocate reliably, as the source shared_ptr could have been created with a
custom deleter, or may have pointed to an object of a different type.

Why is operator->() const, but its return value is a non-const pointer to the element type?

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".

weak_ptr: Non-owning Observer

Description

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 taking
weak_ptr, or the weak_ptr 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 had a get member function that returned a raw pointer, and consider this innocent
piece of code:

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.

swap

Frequently Asked Questions

Can an object create a weak_ptr to itself in its constructor?

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:

make_shared: Creating shared_ptr

Description

Rationale

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
were 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 construction overhead. This eliminates one of the major
efficiency complaints about shared_ptr.

The family of overloaded function templates, make_shared and
allocate_shared, were provided 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.

Originally the Boost function templates allocate_shared and make_shared
were provided for scalar objects only. There was a need to have efficient
allocation of array objects. One criticism of class template shared_array
was always the lack of a utility like make_shared that uses only a single
allocation. When shared_ptr was enhanced to support array types, additional
overloads of allocate_shared and make_shared were provided for array
types.

Synopsis

make_shared and allocate_shared are defined in
<boost/smart_ptr/make_shared.hpp>.

Common Requirements

The common requirements that apply to all make_shared and allocate_shared
overloads, unless specified otherwise, are described below.

Requires

A shall be an allocator. The copy constructor and destructor
of A shall not throw exceptions.

Effects

Allocates memory for an object of type T or n objects of U
(if T is an array type of the form U[] and n is determined by
arguments, as specified by the concrete overload). The object is initialized
from arguments as specified by the concrete overload. Uses a rebound copy of
a (for an unspecified value_type) to allocate memory. If an exception is
thrown, the functions have no effect.

Returns

A shared_ptr instance that stores and owns the address of the
newly constructed object.

Postconditions

r.get() != 0 and r.use_count() == 1, where r
is the return value.

Throws

std::bad_alloc, an exception thrown from A::allocate, or from the
initialization of the object.

Remarks

Performs no more than one memory allocation. This provides efficiency
equivalent to an intrusive smart pointer.

When an object of an array type is specified to be initialized to a value of
the same type v, this shall be interpreted to mean that each array element
of the object is initialized to the corresponding element from v.

When an object of an array type is specified to be value-initialized, this
shall be interpreted to mean that each array element of the object is
value-initialized.

When a (sub)object of non-array type U is specified to be initialized to
a value v, or constructed from args..., make_shared shall perform
this initialization via the expression ::new(p) U(expr) (where
expr is v or std::forward<Args>(args)...) respectively) and p
has type void* and points to storage suitable to hold an object of type
U.

When a (sub)object of non-array type U is specified to be initialized to
a value v, or constructed from args..., allocate_shared shall
perform this initialization via the expression
std::allocator_traits<A2>::construct(a2, p, expr) (where
expr is v or std::forward<Args>(args)...) respectively), p
points to storage suitable to hold an object of type U, and a2 of
type A2 is a rebound copy a such that its value_type is U.

When a (sub)object of non-array type U is specified to be
default-initialized, make_shared_noinit and allocate_shared_noinit shall
perform this initialization via the expression ::new(p) U, where
p has type void* and points to storage suitable to hold an object of
type U.

When a (sub)object of non-array type U is specified to be
value-initialized, make_shared shall perform this initialization via the
expression ::new(p) U(), where p has type void* and points to
storage suitable to hold an object of type U.

When a (sub)object of non-array type U is specified to be
value-initialized, allocate_shared shall perform this initialization via the
expression std::allocator_traits<A2>::construct(a2, p), where
p points to storage suitable to hold an object of type U and a2 of
type A2 is a rebound copy of a such that its value_type is U.

Array elements are initialized in ascending order of their addresses.

When the lifetime of the object managed by the return value ends, or when
the initialization of an array element throws an exception, the initialized
elements should be destroyed in the reverse order of their construction.

Note

These functions will typically allocate more memory than the total size
of the element objects to allow for internal bookkeeping structures such as
the reference counts.

These overloads shall only participate in overload resolution when
T is an array type of the form U[].

Returns

A shared_ptr to a sequence of n default-initialized objects
of type U.

Example

auto p = make_shared_noinit<double[]>(1024);

enable_shared_from_this

Description

The class template enable_shared_from_this is used as a base class that allows
a shared_ptr or a weak_ptr to the current object to be obtained from within a
member function.

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

make_unique: Creating unique_ptr

Description

Rationale

The C++11 standard introduced std::unique_ptr but did not provide any
make_unique utility like std::make_shared that provided the same
exception safety and facility to avoid writing new expressions. Before it
was implemented by some standard library vendors (and prior to the C++14
standard introducing std::make_unique), this library provided it due to
requests from users.

This library also provides additional overloads of make_unique for
default-initialization, when users do not need or want to incur the expense
of value-initialization. The C++ standard does not yet provide this
feature with std::make_unique.

Synopsis

make_unique is defined in <boost/smart_ptr/make_unique.hpp>.

namespace boost {
// only if T is not an array type
template<class T, class... Args>
std::unique_ptr<T> make_unique(Args&&... args);
// only if T is not an array type
template<class T>
std::unique_ptr<T> make_unique(remove_reference_t<T>&& v);
// only if T is an array type of the form U[]
template<class T>
std::unique_ptr<T> make_unique(std::size_t n);
// only if T is not an array type
template<class T>
std::unique_ptr<T> make_unique_noinit();
// only if T is an array type of the form U[]
template<class T>
std::unique_ptr<T> make_unique_noinit(std::size_t n);
}

These overloads shall only participate in overload resolution when
T is an array type of the form U[].

Returns

std::unique_ptr<U[]>(new U[n]).

Example

auto p = make_unique_noinit<double[]>(1024);

intrusive_ptr: Managing Objects with Embedded Counts

Description

The 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.

The class template is parameterized on 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*.

indirection

get

T * get() const noexcept;

Returns

the stored pointer.

detach

T * detach() noexcept;

Returns

the stored pointer.

Postconditions

get() == 0.

Note

The returned pointer has an elevated reference count. This allows conversion of an 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.

Caution

Using 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

explicit operator bool () const noexcept;

Returns

get() != 0.

Note

This conversion operator allows intrusive_ptr objects to be used in boolean contexts,
like if (p && p->valid()) {}.

operator<<

intrusive_ref_counter

Description

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. 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 Derived and CounterPolicy
parameters. 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. The library provides two such policies: thread_unsafe_counter and
thread_safe_counter. The former instructs the intrusive_ref_counter base
class to use a counter only suitable for a single-threaded use. Pointers to a
single object that uses this kind of reference counter must not be used in
different threads. The latter policy makes the reference counter thread-safe,
unless the target platform doesn’t support threading. Since in modern systems
support for threading is common, the default counter policy is
thread_safe_counter.

Synopsis

intrusive_ref_counter is defined in
<boost/smart_ptr/intrusive_ref_counter.hpp>.

local_shared_ptr: Shared Ownership within a Single Thread

Description

local_shared_ptr is nearly identical to shared_ptr, with the only difference of note being that its reference count is
updated with non-atomic operations. As such, a local_shared_ptr and all its copies must reside in (be local to) a single
thread (hence the name.)

local_shared_ptr can be converted to shared_ptr and vice versa. Creating a local_shared_ptr from a shared_ptr creates
a new local reference count; this means that two local_shared_ptr instances, both created from the same shared_ptr, refer
to the same object but don’t share the same count, and as such, can safely be used by two different threads.

Code Example 9. Two local_shared_ptr instances created from a shared_ptr

One can think of local_shared_ptr<T> as shared_ptr<shared_ptr<T>>, with the outer shared_ptr using non-atomic operations for
its count. Converting from local_shared_ptr to shared_ptr gives you a copy of the inner shared_ptr; converting from shared_ptr
wraps it into an outer shared_ptr with a non-atomic use count (conceptually speaking) and returns the result.

Synopsis

local_shared_ptr is defined in <boost/smart_ptr/local_shared_ptr.hpp>.

get_deleter

make_local_shared: Creating local_shared_ptr

Description

The function templates make_local_shared and allocate_local_shared provide
convenient, safe and efficient ways to create local_shared_ptr objects. They
are analogous to make_shared and allocate_shared for shared_ptr.

Synopsis

make_local_shared and allocate_local_shared are defined in
<boost/smart_ptr/make_local_shared.hpp>.

Pointer cast functions templates are overloads of static_pointer_cast,
dynamic_pointer_cast, const_pointer_cast, and reinterpret_pointer_cast
for raw pointers, std::shared_ptr and std::unique_ptr. 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.

Description

Rationale

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.)

This technique relies on shared_ptr’s ability to execute a custom deleter, eliminating the explicit call to fclose, and on the fact that shared_ptr<X> can be copied and destroyed when X 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":

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 is CopyConstructible and Assignable, 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:

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; the shared_ptr<X> instance returned from createX 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:

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, where CreateX might allocate X from its own private heap, ~X may
be inaccessible, or X may be incomplete:

X * CreateX();
void DestroyX(X *);

The only way to reliably destroy a pointer returned by CreateX is to call DestroyX.

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 object

Sometimes it is desirable to create a shared_ptr to an already existing object, so that the shared_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.

Using a shared_ptr to hold a pointer to a COM Object

Background: 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.

Note, however, that shared_ptr copies created from pw will not "register" in the embedded count of the COM object;
they will share the single reference created in make_shared_from_COM. Weak pointers created from pw will be invalidated when the last
shared_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 count

This 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 and intrusive_ptr_release:

Using a shared_ptr to hold another shared ownership smart pointer

One 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 a
shared_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 a shared_ptr facade:

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 a try {} 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:

Obtaining a shared_ptr from a raw pointer

Sometimes it is necessary to obtain a shared_ptr given a raw pointer to an object that is already managed by another shared_ptr instance. Example:

void f(X * p)
{
shared_ptr<X> px(???);
}

Inside f, we’d like to create a shared_ptr to *p.

In the general case, this problem has no solution. One approach is to modify f to take a shared_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);

would become a free function with a shared_ptr first argument:

void f(shared_ptr<X> this_, int m);

If f cannot be changed, but X uses intrusive counting, use make_shared_from_intrusive described above. Or, if it’s known that the shared_ptr created in f will never outlive the object, use a null deleter.

Obtaining a shared_ptr (weak_ptr) to this in a constructor

Some 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:
X()
{
shared_ptr<X> this_(???);
}
};

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 another shared_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 a null_deleter as explained here and here.
If X is supposed to always live on the heap, and be managed by a shared_ptr, use a static factory function:

Obtaining a shared_ptr to this

Sometimes it is needed to obtain a shared_ptr from this in a virtual member function under the assumption that this is already managed by a shared_ptr.
The transformations described in the previous technique cannot be applied.

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), where p 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));

Using shared_ptr<void> to hold an arbitrary object

shared_ptr<void> can act as a generic object pointer similar to void*. When a shared_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.
A shared_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 and weak_ptr support operator< comparisons required by standard associative containers such as std::map. This can be
used to non-intrusively associate arbitrary data with objects managed by shared_ptr:

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 the Wrap/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:

When the object’s lifetime ends, X::this_ will be destroyed, and all weak pointers will automatically expire.

Appendix B: History and Acknowledgments

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. 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.

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.

May 1999

In April and May, 1999, Valentin Bonnard and David Abrahams made a number of suggestions resulting in numerous improvements.

January 2002

Peter Dimov reworked all four classes, adding features, fixing bugs, splitting them into four separate headers, and adding
weak_ptr.

March 2003

Peter Dimov, Beman Dawes and Greg Colvin proposedshared_ptr
and weak_ptr for inclusion in the Standard Library via the first Library Technical Report (known as TR1). The proposal was
accepted and eventually went on to become a part of the C++ standard in its 2011 iteration.

July 2007

Peter Dimov and Beman Dawes proposed a number of enhancements
to shared_ptr as it was entering the working paper that eventually became the C++11 standard.

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.

Peter Dimov aided this development by extending shared_ptr to support arrays via the syntax shared_ptr<T[]> and shared_ptr<T[N]>.

April 2013

Peter Dimov proposed the extension of shared_ptr to support
arrays for inclusion into the standard, and it was accepted.

February 2014

Glen Fernandes updated make_shared and allocate_shared to conform to the specification in C++ standard paper
N3870, and implemented make_unique for arrays and objects.

June 2017

Appendix C: shared_array (deprecated)

Note

This facility is deprecated because a shared_ptr to T[] or T[N]
is now available, and is superior in every regard.

Description

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, the use
count of A 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.
shared_array and most of its member functions place no requirements on T;
it is allowed to be an incomplete type, or void. Member functions that do
place additional requirements (constructors, reset) are explicitly documented
below.

Members

element_type

typedef T element_type;

Type

Provides the type of the stored pointer.

Constructors

explicit shared_array(T* p = 0);

Effects

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).

Requires

T is a complete type.

Throws

std::bad_alloc. If an exception is thrown, delete[] p is called.

template<class D> shared_array(T* p, D d);

Effects

Constructs a shared_array, storing a copy of p and of d.
Afterwards, the use count is 1. When the the time comes to delete the array
pointed to by p, the object d is used in the statement d(p).

Requires

T is a complete type.

The copy constructor and destructor of D must not throw.

Invoking the object d with parameter p must not throw.

Throws

std::bad_alloc. If an exception is thrown, d(p) is called.

shared_array(const shared_array& v) noexcept;

Effects

Constructs a shared_array, as if by storing a copy of the pointer
stored in v. Afterwards, the use count for all copies is 1 more than the
initial use count.

Requires

T is a complete type.

Destructor

~shared_array() noexcept;

Effects

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.

Assignment

shared_array& operator=(const shared_array& v) noexcept;

Effects

Constructs a new shared_array as described above, then replaces
this shared_array with the new one, destroying the replaced object.

Requires

T is a complete type.

Returns

*this.

reset

void reset(T* p = 0);

Effects

Constructs a new shared_array as described above, then replaces
this shared_array with the new one, destroying the replaced object.

Requires

T is a complete type.

Throws

std::bad_alloc. If an exception is thrown, delete[] p is called.

template<class D> void reset(T* p, D d);

Effects

Constructs a new shared_array as described above, then replaces
this shared_array with the new one, destroying the replaced object.

Requires

T is a complete type.

The copy constructor of D must not throw.

Throws

std::bad_alloc. If an exception is thrown, d(p) is called.

Indexing

T& operator[](std::ptrdiff_t n) const noexcept;

Returns

A reference to element n of the array pointed to by the stored
pointer. Behavior is undefined and almost certainly undesirable if the stored
pointer is 0, or if n is less than 0 or is greater than or equal to the
number of elements in the array.

Requires

T is a complete type.

get

T* get() const noexcept;

Returns

The stored pointer.

unique

bool unique() const noexcept;

Returns

true if no other shared_array is sharing ownership of the
stored pointer, false otherwise.

use_count

long use_count() const noexcept;

Returns

The number of shared_array objects sharing ownership of the
stored pointer.

The result of comparing the stored pointers of the two smart
pointers.

Note

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).