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) | (depuis 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) | (supprimé en C++17) |
|
template
<
class
Y,
class
Deleter
>
shared_ptr ( std:: unique_ptr < Y, Deleter > && r ) ; |
(13) | |
Construit un nouveau
shared_ptr
à partir de divers types de pointeurs qui référencent un objet à gérer.
|
Aux fins de la description ci-dessous, un type pointeur
|
(depuis C++17) |
shared_ptr
sans objet géré, c'est-à-dire un
shared_ptr
vide.
shared_ptr
avec
ptr
comme pointeur vers l'objet géré.
|
Pour
(3,4,6)
,
|
(jusqu'à C++17) |
|
Si
|
(depuis C++17) |
T
n'est pas un type tableau ;
delete
[
]
ptr
si
T
est un type tableau
(depuis C++17)
comme suppresseur.
Y
doit être un type complet. L'expression delete doit être bien formée, avoir un comportement bien défini et ne lever aucune exception.
Ce constructeur ne participe en outre pas à la résolution de surcharge si l'expression delete n'est pas bien formée.
(depuis C++17)
|
|
(jusqu'à C++17) |
|
Ces constructeurs ne participent pas non plus à la résolution de surcharge si l'expression d ( ptr ) n'est pas bien formée, ou si std:: is_move_constructible_v < D > est false . |
(depuis C++17) |
Alloc
doit être un
Allocator
.
shared_ptr
qui partage les informations de propriété avec la valeur initiale de
r
, mais contient un pointeur non lié et non géré
ptr
. Si ce
shared_ptr
est le dernier du groupe à sortir de la portée, il appellera le destructeur stocké pour l'objet initialement géré par
r
. Cependant, l'appel à
get()
sur ce
shared_ptr
retournera toujours une copie de
ptr
. Il est de la responsabilité du programmeur de s'assurer que ce
ptr
reste valide tant que ce shared_ptr existe, comme dans les cas d'utilisation typiques où
ptr
est un membre de l'objet géré par
r
ou est un alias (par exemple, downcast) de
r.get()
Pour la seconde surcharge preant une rvalue,
r
est vide et
r.
get
(
)
==
nullptr
après l'appel.
(depuis C++20)
shared_ptr
qui partage la propriété de l'objet géré par
r
. Si
r
ne gère aucun objet,
*
this
ne gère aucun objet non plus. La surcharge de modèle ne participe pas à la résolution de surcharge si
Y*
n'est pas
implicitement convertible en
(until C++17)
compatible avec
(since C++17)
T*
.
shared_ptr
à partir de
r
. Après la construction,
*
this
contient une copie de l'état précédent de
r
,
r
est vide et son pointeur stocké est nul. La surcharge du modèle ne participe pas à la résolution de surcharge si
Y*
n'est pas
implicitement convertible en
(jusqu'à C++17)
compatible avec
(depuis C++17)
T*
.
shared_ptr
qui partage la propriété de l'objet géré par
r
.
Y*
doit être implicitement convertible en
T*
.
(jusqu'en C++17)
Cette surcharge participe à la résolution de surcharge seulement si
Y*
est compatible avec
T*
.
(depuis C++17)
Notez que
r.
lock
(
)
peut être utilisé dans le même but : la différence est que ce constructeur lance une exception si l'argument est vide, tandis que
std::
weak_ptr
<
T
>
::
lock
(
)
construit un
std::shared_ptr
vide dans ce cas.
shared_ptr
qui stocke et possède l'objet précédemment détenu par
r
.
Y*
doit être convertible en
T*
. Après la construction,
r
est vide.
shared_ptr
qui gère l'objet actuellement géré par
r
. Le deleter associé à
r
est stocké pour la future suppression de l'objet géré.
r
ne gère aucun objet après l'appel.
Cette surcharge ne participe pas à la résolution de surcharge si
std::unique_ptr<Y, Deleter>::pointer
n'est pas
compatible avec
T*
.
Si
r.
get
(
)
est un pointeur nul, cette surcharge est équivalente au constructeur par défaut
(1)
.
|
(depuis C++17) |
Deleter
est un type référence, c'est équivalent à
shared_ptr
(
r.
release
(
)
,
std::
ref
(
r.
get_deleter
(
)
)
. Sinon, c'est équivalent à
shared_ptr
(
r.
release
(
)
, std
::
move
(
r.
get_deleter
(
)
)
)
.
Lorsque
T
n'est pas un type tableau, les surcharges
(3,4,6)
activent
shared_from_this
avec
ptr
, et la surcharge
(13)
active
shared_from_this
avec le pointeur retourné par
r.
release
(
)
.
Table des matières |
Paramètres
| ptr | - | un pointeur vers un objet à gérer |
| d | - | un suppresseur à utiliser pour détruire l'objet |
| alloc | - | un allocateur à utiliser pour les allocations de données à usage interne |
| r | - | un autre pointeur intelligent avec lequel partager la propriété ou dont acquérir la propriété |
Postconditions
Exceptions
T
n'est pas un type tableau, et appelle
delete
[
]
ptr
sinon
(depuis C++17)
.
Notes
Un constructeur
active
shared_from_this
avec un pointeur
ptr
de type
U*
signifie qu'il détermine si
U
possède une classe de base
non ambiguë et accessible
(depuis C++17)
qui est une spécialisation de
std::enable_shared_from_this
, et si c'est le cas, le constructeur évalue
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
)
)
;
.
L'assignation à
weak_this
n'est pas atomique et entre en conflit avec tout accès potentiellement concurrent au même objet. Cela garantit que les appels futurs à
shared_from_this()
partageront la propriété avec le
std::shared_ptr
créé par ce constructeur de pointeur brut.
Le test
ptr
-
>
weak_this
.
expired
(
)
dans le code ci-dessus garantit que
weak_this
n'est pas réaffecté s'il indique déjà un propriétaire. Ce test est requis à partir de C++17.
Les surcharges de pointeur brut prennent la propriété de l'objet pointé. Par conséquent, construire un
shared_ptr
en utilisant la surcharge de pointeur brut pour un objet déjà géré par un
shared_ptr
, comme par
shared_ptr
(
ptr.
get
(
)
)
est susceptible de conduire à un comportement indéfini, même si l'objet est d'un type dérivé de
std::enable_shared_from_this
.
Parce que le constructeur par défaut est
constexpr
, les shared_ptrs statiques sont initialisés dans le cadre de
l'initialisation statique non locale
, avant que toute initialisation dynamique non locale ne commence. Cela rend sûr d'utiliser un shared_ptr dans le constructeur de tout objet statique.
En C++11 et C++14, il est valide de construire un std:: shared_ptr < T > à partir d'un std:: unique_ptr < T [ ] > :
std::unique_ptr<int[]> arr(new int[1]); std::shared_ptr<int> ptr(std::move(arr));
` et contient des termes spécifiques au C++ qui doivent être préservés. Le code reste donc identique à l'original.
Puisque le
shared_ptr
obtient son suppresseur (un objet
std::
default_delete
<
T
[
]
>
) du
std::unique_ptr
, le tableau sera correctement désalloué.
Ceci n'est plus autorisé en C++17. À la place, la forme tableau std:: shared_ptr < T [ ] > devrait être utilisée.
Exemple
#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; }); } }
Sortie :
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
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | S'applique à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 3548 | C++11 |
le constructeur depuis
unique_ptr
copiait le deleter
|
le déplace à la place |
Voir aussi
|
crée un pointeur partagé qui gère un nouvel objet
(modèle de fonction) |
|
|
crée un pointeur partagé qui gère un nouvel objet alloué à l'aide d'un allocateur
(modèle de fonction) |
|
|
(C++11)
|
permet à un objet de créer un
shared_ptr
se référant à lui-même
(modèle de classe) |