constexpr shared_ptr() noexcept;
(1) (2)template< class Y >
explicit shared_ptr( Y* ptr );
template< class Y, class Deleter >
shared_ptr( Y* ptr, Deleter d );
template< class Y, class Deleter, class Alloc >
shared_ptr( Y* ptr, Deleter d, Alloc alloc );
template< class Y >
shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept;
template< class Y >
shared_ptr( shared_ptr<Y>&& r, element_type* ptr ) noexcept;
shared_ptr( const shared_ptr& r ) noexcept;
(9)template< class Y >
shared_ptr( const shared_ptr<Y>& r ) noexcept;
shared_ptr( shared_ptr&& r ) noexcept;
(10)template< class Y >
shared_ptr( shared_ptr<Y>&& r ) noexcept;
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 Y*
is said to be compatible with a pointer type T*
if either Y*
is convertible to T*
or Y
is the array type U[N]
and T
is U cv []
(where cv is some set of cv-qualifiers).
1,2) Constructs a shared_ptr
with no managed object, i.e. empty shared_ptr
.
Constructs a
shared_ptr
with
ptras the pointer to the managed object.
For (3,4,6), Y*
must be convertible to T*
.
If T
is an array type U[N]
, (3,4,6) do not participate in overload resolution if Y(*)[N]
is an invalid type or not convertible to T*
. If T
is an array type U[]
, (3,4,6) do not participate in overload resolution if Y(*)[]
is an invalid type or not convertible to T*
. Otherwise, (3,4,6) do not participate in overload resolution if Y*
is not convertible to T*
.
Additionally:
3)Uses the
delete-expression delete ptr ifT
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) 4,5)Uses the specified deleter
das the deleter. The expression
d(ptr)must be well formed, have well-defined behavior and not throw any exceptions. The construction of
dand of the stored deleter copied from it must not throw exceptions.
Deleter
must be CopyConstructible.
These constructors additionally do not participate in overload resolution if the expression d(ptr) is not well-formed, or if std::is_move_constructible_v<D> is false.
(since C++17) 6,7)Same as
(4,5), but additionally uses a copy of
allocfor allocation of data for internal use.
Alloc
must be an
Allocator.
8) The aliasing constructor: constructs a 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)
9) Constructs a 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*
.
10) Move-constructs a 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*
.
Constructs a
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.
12) Constructs a shared_ptr
that stores and owns the object formerly owned by r. Y*
must be convertible to T*
. After construction, r is empty.
Constructs a
shared_ptr
which manages the object currently managed by
r. The deleter associated with
ris stored for future deletion of the managed object.
rmanages no object after the call.
This overload doesn't participate in overload resolution ifstd::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)
If
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,6) enable shared_from_this
with ptr, and the overload (13) enables shared_from_this
with the pointer returned by r.release().
equals
ptr. For the second overload,
ris empty and
r.get()equals
nullptr.
10) r shall be empty and r.get() shall equal nullptr, and *this shall be the old value of r.
[edit] Exceptions 3) std::bad_allocif required additional memory could not be obtained. May throw implementation-defined exception for other errors. If an exception occurs, this calls
delete ptr ifT
is not an array type, and calls delete[] ptr otherwise(since C++17)
.
4-7) std::bad_allocif required additional memory could not be obtained. May throw implementation-defined exception for other errors.
d(ptr)is called if an exception occurs.
11) std::bad_weak_ptrif
r.expired() == true. The constructor has no effect in this case.
12) std::bad_allocif required additional memory could not be obtained. May throw implementation-defined exception for other errors. This constructor has no effect if an exception occurs.
13) If an exception is thrown, the constructor has no effects.
[edit] NotesA 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 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)); .
The assignment to the weak_this
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 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[]>:
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.
[edit] Example#include <iostream> #include <memory> 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[edit] 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 fromunique_ptr
copy-constructed the deleter move-constructs instead [edit] See also
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4