|
|
Member functions | ||||
shared_ptr::shared_ptr | ||||
Modifiers | ||||
Observers | ||||
(C++17) | ||||
(until C++20*) | ||||
(C++26) | ||||
(C++26) | ||||
Non-member functions | ||||
(until C++20)(until C++20)(until C++20)(until C++20)(until C++20)(C++20) | ||||
functions(until C++26*) | ||||
Helper classes | ||||
(C++20) | ||||
Deduction guides(C++17) |
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(conststd::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 newshared_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. emptyshared_ptr
.shared_ptr
withptr as the pointer to the managed object.For(3,4,6), | (until C++17) |
If | (since C++17) |
T
is not an array type;delete[] ptr ifT
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)
| (until C++17) |
These constructors additionally do not participate in overload resolution if the expressiond(ptr) is not well-formed, or ifstd::is_move_constructible_v<D> isfalse. | (since C++17) |
Alloc
must be anAllocator.shared_ptr
which shares ownership information with the initial value ofr, but holds an unrelated and unmanaged pointerptr. If thisshared_ptr
is the last of the group to go out of scope, it will call the stored deleter for the object originally managed byr. However, callingget()
on thisshared_ptr
will always return a copy ofptr. It is the responsibility of the programmer to make sure that thisptr remains valid as long as this shared_ptr exists, such as in the typical use cases whereptr is a member of the object managed byr or is an alias (e.g., downcast) ofr.get()
For the second overload taking an rvalue,r is empty andr.get()== nullptr after the call.(since C++20)shared_ptr
which shares ownership of the object managed byr. Ifr manages no object,*this manages no object either. The template overload doesn't participate in overload resolution ifY*
is notimplicitly convertible to(until C++17)compatible with(since C++17)T*
.shared_ptr
fromr. After the construction,*this contains a copy of the previous state ofr,r is empty and its stored pointer is null. The template overload doesn't participate in overload resolution ifY*
is notimplicitly convertible to(until C++17)compatible with(since C++17)T*
.shared_ptr
which shares ownership of the object managed byr.Y*
must be implicitly convertible toT*
.(until C++17)This overload participates in overload resolution only ifY*
is compatible withT*
.(since C++17) Note thatr.lock() may be used for the same purpose: the difference is that this constructor throws an exception if the argument is empty, whilestd::weak_ptr<T>::lock() constructs an emptystd::shared_ptr
in that case.shared_ptr
that stores and owns the object formerly owned byr.Y*
must be convertible toT*
. After construction,r is empty.shared_ptr
which manages the object currently managed byr. The deleter associated withr is stored for future deletion of the managed object.r manages no object after the call.This overload doesn't participate in overload resolution ifstd::unique_ptr<Y, Deleter>::pointer is notcompatible withT* .Ifr.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 toshared_ptr(r.release(),std::ref(r.get_deleter()). Otherwise, it is equivalent toshared_ptr(r.release(), std::move(r.get_deleter())).WhenT
is not an array type, the overloads(3,4,6) enableshared_from_this
withptr, and the overload(13) enablesshared_from_this
with the pointer returned byr.release().
Contents |
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 |
T
is not an array type, and callsdelete[] ptr otherwise(since C++17).A constructorenablesshared_from_this
with a pointerptr of typeU*
means that it determines ifU
has anunambiguous and accessible(since C++17) base class that is a specialization ofstd::enable_shared_from_this, and if so, the constructor evaluatesif(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 theweak_this
is not atomic and conflicts with any potentially concurrent access to the same object. This ensures that future calls toshared_from_this() would share ownership with thestd::shared_ptr created by this raw pointer constructor.
The testptr->weak_this
.expired() in the code above makes sure thatweak_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 ashared_ptr
using the raw pointer overload for an object that is already managed by ashared_ptr
, such as byshared_ptr(ptr.get()) is likely to lead to undefined behavior, even if the object is of a type derived fromstd::enable_shared_from_this.
Because the default constructor isconstexpr
, static shared_ptrs are initialized as part ofstatic 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 astd::shared_ptr<T> from astd::unique_ptr<T[]>:
std::unique_ptr<int[]> arr(newint[1]);std::shared_ptr<int> ptr(std::move(arr));
Since theshared_ptr
obtains its deleter (astd::default_delete<T[]> object) from thestd::unique_ptr, the array will be correctly deallocated.
This is no longer allowed in C++17. Instead the array formstd::shared_ptr<T[]> should be used.
#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 object2) constructor with objectFoo::Foo(10)sh2.use_count(): 1sh2.use_count(): 2sh3.use_count(): 2Foo::~Foo(), id=103) constructor with object and deleterFoo::Foo(11)Foo::Foo(12)Call delete from lambda... p->id=12Foo::~Foo(), id=12Call delete from function object. Foo::id=11Foo::~Foo(), id=11
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 |
creates a shared pointer that manages a new object (function template)[edit] | |
creates a shared pointer that manages a new object allocated using an allocator (function template)[edit] | |
(C++11) | allows an object to create ashared_ptr referring to itself(class template)[edit] |