std::shared_ptr<T>::shared_ptr
constexpr shared_ptr() noexcept; |
(1) | |
constexpr shared_ptr( std::nullptr_t ) noexcept; |
(2) | |
template< class Y > explicit shared_ptr( Y* ptr ); |
(3) | |
template< class Y, class Deleter > shared_ptr( Y* ptr, Deleter d ); |
(4) | |
template< class Deleter > shared_ptr( std::nullptr_t ptr, Deleter d ); |
(5) | |
template< class Y, class Deleter, class Alloc > shared_ptr( Y* ptr, Deleter d, Alloc alloc ); |
(6) | |
template< class Deleter, class Alloc > shared_ptr( std::nullptr_t ptr, Deleter d, Alloc alloc ); |
(7) | |
template< class Y > shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept; |
(8) | |
template< class Y > shared_ptr( shared_ptr<Y>&& r, element_type* ptr ) noexcept; |
(8) | (since C++20) |
shared_ptr( const shared_ptr& r ) noexcept; |
(9) | |
template< class Y > shared_ptr( const shared_ptr<Y>& r ) noexcept; |
(9) | |
shared_ptr( shared_ptr&& r ) noexcept; |
(10) | |
template< class Y > shared_ptr( shared_ptr<Y>&& r ) noexcept; |
(10) | |
template< class Y > explicit shared_ptr( const std::weak_ptr<Y>& r ); |
(11) | |
template< class Y > shared_ptr( std::auto_ptr<Y>&& r ); |
(12) | (removed in C++17) |
template< class Y, class Deleter > shared_ptr( std::unique_ptr<Y, Deleter>&& r ); |
(13) |
Constructs new shared_ptr
from a variety of pointer types that refer to an object to manage.
For the purposes of the description below, a pointer type |
(since C++17) |
shared_ptr
with no managed object, i.e. empty
shared_ptr
shared_ptr
with
ptr
as the pointer to the managed object.
For (3-4,6), |
(until C++17) |
If |
(since C++17) |
delete ptr
if T
is not an array type; delete[] ptr
if T
is an array type (since C++17) as the deleter.
Y
must be a complete type. The delete expression must be well-formed, have well-defined behavior and not throw any exceptions.
This constructor additionally does not participate in overload resolution if the delete expression is not well-formed. (since C++17)
d
as the deleter. The expression
d(ptr)
must be well formed, have well-defined behavior and not throw any exceptions. The construction of
d
and of the stored deleter from
d
must not throw exceptions.
|
(until C++17) |
These constructors additionally do not participate in overload resolution if the expression |
(since C++17) |
alloc
for allocation of data for internal use.
Alloc
must be an
Allocator.
shared_ptr
which shares ownership information with the initial value of
r
, but holds an unrelated and unmanaged pointer
ptr
. If this
shared_ptr
is the last of the group to go out of scope, it will call the stored deleter for the object originally managed by
r
. However, calling
get()
on this
shared_ptr
will always return a copy of
ptr
. It is the responsibility of the programmer to make sure that this
ptr
remains valid as long as this shared_ptr exists, such as in the typical use cases where
ptr
is a member of the object managed by
r
or is an alias (e.g., downcast) of
r.get()
For the second overload taking an rvalue, r
is empty and r.get() == nullptr
after the call. (since C++20)
shared_ptr
which shares ownership of the object managed by
r
. If
r
manages no object,
*this
manages no object either. The template overload doesn't participate in overload resolution if
Y*
is not
implicitly convertible to (until C++17)
compatible with (since C++17)
T*
.
shared_ptr
from
r
. After the construction,
*this
contains a copy of the previous state of
r
,
r
is empty and its stored pointer is null. The template overload doesn't participate in overload resolution if
Y*
is not
implicitly convertible to (until C++17)
compatible with (since C++17)
T*
.
shared_ptr
which shares ownership of the object managed by
r
.
Y*
must be implicitly convertible to T*
. (until C++17)
This overload participates in overload resolution only if Y*
is compatible with T*
. (since C++17) Note that
r.lock()
may be used for the same purpose: the difference is that this constructor throws an exception if the argument is empty, while
std::weak_ptr<T>::lock()
constructs an empty
std::shared_ptr
in that case.
shared_ptr
that stores and owns the object formerly owned by
r
.
Y*
must be convertible to
T*
. After construction,
r
is empty.
shared_ptr
which manages the object currently managed by
r
. The deleter associated with
r
is stored for future deletion of the managed object.
r
manages no object after the call.
This overload doesn't participate in overload resolution if std::unique_ptr<Y, Deleter>::pointer is not compatible with T* . If r.get() is a null pointer, this overload is equivalent to the default constructor (1). |
(since C++17) |
Deleter
is a reference type, it is equivalent to
shared_ptr(r.release(), std::ref(r.get_deleter())
. Otherwise, it is equivalent to
shared_ptr(r.release(), std::move(r.get_deleter()))
When T
is not an array type, the overloads (3), (4), and (6) enable shared_from_this
with ptr
, and the overload (13) enables shared_from_this
with the pointer returned by r.release()
.
Parameters
ptr | - | a pointer to an object to manage |
d | - | a deleter to use to destroy the object |
alloc | - | an allocator to use for allocations of data for internal use |
r | - | another smart pointer to share the ownership to or acquire the ownership from |
Exceptions
std::bad_alloc
if required additional memory could not be obtained. May throw implementation-defined exception for other errors. If an exception occurs, this calls
delete ptr
if T
is not an array type, and calls delete[] ptr
otherwise (since C++17).
std::bad_alloc
if required additional memory could not be obtained. May throw implementation-defined exception for other errors.
d(ptr)
is called if an exception occurs.
std::bad_alloc
if required additional memory could not be obtained. May throw implementation-defined exception for other errors. This constructor has no effect if an exception occurs.
Notes
A constructor enables shared_from_this
with a pointer ptr
of type U*
means that it determines if U
has an unambiguous and accessible (since C++17) base class that is a specialization of std::enable_shared_from_this
, and if so, the constructor evaluates the statement:
if (ptr != nullptr && ptr->weak_this.expired()) ptr->weak_this = std::shared_ptr<std::remove_cv_t<U>>(*this, const_cast<std::remove_cv_t<U>*>(ptr));
Where weak_this
is the hidden mutable std::weak_ptr
member of std::enable_shared_from_this
. The assignment to the weak_this
member is not atomic and conflicts with any potentially concurrent access to the same object. This ensures that future calls to shared_from_this()
would share ownership with the std::shared_ptr
created by this raw pointer constructor.
The test ptr->weak_this.expired()
in the exposition code above makes sure that weak_this
is not reassigned if it already indicates an owner. This test is required as of C++17.
The raw pointer overloads assume ownership of the pointed-to object. Therefore, constructing a shared_ptr
using the raw pointer overload for an object that is already managed by a shared_ptr
, such as by shared_ptr(ptr.get())
is likely to lead to undefined behavior, even if the object is of a type derived from std::enable_shared_from_this
.
Because the default constructor is constexpr
, static shared_ptrs are initialized as part of static non-local initialization, before any dynamic non-local initialization begins. This makes it safe to use a shared_ptr in a constructor of any static object.
In C++11 and C++14 it is valid to construct a std::shared_ptr<T>
from a std::unique_ptr<T[]>
:
std::unique_ptr<int[]> arr(new int[1]); std::shared_ptr<int> ptr(std::move(arr));
Since the shared_ptr
obtains its deleter (a std::default_delete<T[]>
object) from the std::unique_ptr
, the array will be correctly deallocated.
This is no longer allowed in C++17. Instead the array form std::shared_ptr<T[]>
should be used.
Example
#include <memory> #include <iostream> struct Foo { int id{0}; Foo(int i = 0) : id{i} { std::cout << "Foo::Foo(" << i << ")\n"; } ~Foo() { std::cout << "Foo::~Foo(), id=" << id << '\n'; } }; struct D { void operator()(Foo* p) const { std::cout << "Call delete from function object. Foo::id=" << p->id << '\n'; delete p; } }; int main() { { std::cout << "1) constructor with no managed object\n"; std::shared_ptr<Foo> sh1; } { std::cout << "2) constructor with object\n"; std::shared_ptr<Foo> sh2(new Foo{10}); std::cout << "sh2.use_count(): " << sh2.use_count() << '\n'; std::shared_ptr<Foo> sh3(sh2); std::cout << "sh2.use_count(): " << sh2.use_count() << '\n'; std::cout << "sh3.use_count(): " << sh3.use_count() << '\n'; } { std::cout << "3) constructor with object and deleter\n"; std::shared_ptr<Foo> sh4(new Foo{11}, D()); std::shared_ptr<Foo> sh5(new Foo{12}, [](auto p) { std::cout << "Call delete from lambda... p->id=" << p->id << "\n"; delete p; }); } }
Output:
1) constructor with no managed object 2) constructor with object Foo::Foo(10) sh2.use_count(): 1 sh2.use_count(): 2 sh3.use_count(): 2 Foo::~Foo(), id=10 3) constructor with object and deleter Foo::Foo(11) Foo::Foo(12) Call delete from lambda... p->id=12 Foo::~Foo(), id=12 Call delete from function object. Foo::id=11 Foo::~Foo(), id=11
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 3548 | C++11 | the constructor from unique_ptr copy-constructed the deleter |
move-constructs instead |
See also
(C++20)
|
creates a shared pointer that manages a new object (function template) |
(C++20)
|
creates a shared pointer that manages a new object allocated using an allocator (function template) |
(C++11)
|
allows an object to create a shared_ptr referring to itself (class template) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr