std:: make_shared, std:: make_shared_for_overwrite
|
Défini dans l'en-tête
<memory>
|
||
|
template
<
class
T,
class
...
Args
>
shared_ptr < T > make_shared ( Args && ... args ) ; |
(1) | (depuis C++11) |
|
template
<
class
T
>
shared_ptr < T > make_shared ( std:: size_t N ) ; |
(2) | (depuis C++20) |
|
template
<
class
T
>
shared_ptr < T > make_shared ( ) ; |
(3) | (depuis C++20) |
|
template
<
class
T
>
shared_ptr < T > make_shared ( std:: size_t N, const std:: remove_extent_t < T > & u ) ; |
(4) | (depuis C++20) |
|
template
<
class
T
>
shared_ptr < T > make_shared ( const std:: remove_extent_t < T > & u ) ; |
(5) | (depuis C++20) |
|
template
<
class
T
>
shared_ptr < T > make_shared_for_overwrite ( ) ; |
(6) | (depuis C++20) |
|
template
<
class
T
>
shared_ptr < T > make_shared_for_overwrite ( std:: size_t N ) ; |
(7) | (depuis C++20) |
Alloue de la mémoire pour un objet et initialise l'objet avec les arguments fournis. Retourne un std::shared_ptr gérant l'objet nouvellement créé.
T
, et est construit comme par
::
new
(
pv
)
T
(
std::
forward
<
Args
>
(
args
)
...
)
, où
pv
est un pointeur
void
*
vers un espace de stockage adapté pour contenir un objet de type
T
. Si l'objet doit être détruit, il est détruit comme par
pt
-
>
~T
(
)
, où
pt
est un pointeur vers cet objet de type
T
.
|
Cette surcharge participe à la résolution de surcharge seulement si
|
(depuis C++20) |
T
est un type de tableau non borné.
T
. Chaque élément a une valeur initiale par défaut.
T
est un type tableau borné.
T
est un type de tableau non borné.
T
. Chaque élément a la valeur initiale
u
.
T
est un type de tableau borné.
T
.
-
Si
Tn'est pas un type tableau, l'objet est construit comme par :: new ( pv ) T , où pv est un pointeur void * vers un espace de stockage adapté pour contenir un objet de typeT. Si l'objet doit être détruit, il est détruit comme par pt - > ~T ( ) , où pt est un pointeur vers cet objet de typeT. -
Si
Test un type tableau à taille fixe, la valeur initiale est non spécifiée pour chaque élément.
T
n'est pas un type tableau ou est un type tableau à taille fixe.
T
est un type de tableau non borné.
Initialisation et destruction des éléments du tableau
Les éléments du tableau de type
2,3)
::
new
(
pv
)
U
(
)
4,5)
::
new
(
pv
)
U
(
u
)
6,7)
::
new
(
pv
)
U
Lorsque la durée de vie de l'objet géré par le std::shared_ptr retourné se termine, ou lorsque l'initialisation d'un élément du tableau lève une exception, les éléments initialisés sont détruits dans l'ordre inverse de leur construction initiale.
Pour chaque élément du tableau de type non-tableau
|
(depuis C++20) |
Paramètres
| args | - |
liste d'arguments avec lesquels un objet de
T
sera construit
|
| N | - | taille du tableau à utiliser |
| u | - | la valeur initiale pour initialiser chaque élément du tableau |
Valeur de retour
std::shared_ptr
vers un objet de type
T
ou
std::
remove_extent_t
<
T
>
[
N
]
si
T
est un type de tableau non borné
(depuis C++20)
.
Pour le std::shared_ptr r retourné, r. get ( ) renvoie un pointeur non nul et r. use_count ( ) renvoie 1 .
Exceptions
Peut lever
std::bad_alloc
ou toute exception levée par le constructeur de
T
. Si une exception est levée, les fonctions n'ont aucun effet.
Si une exception est levée durant la construction du tableau, les éléments déjà initialisés sont détruits dans l'ordre inverse.
(depuis C++20)
Notes
Ces fonctions allouent généralement plus de mémoire que sizeof ( T ) pour permettre des structures de gestion internes telles que les compteurs de référence.
Ces fonctions peuvent être utilisées comme alternative à std:: shared_ptr < T > ( new T ( args... ) ) . Les compromis sont :
-
std::
shared_ptr
<
T
>
(
new T
(
args...
)
)
effectue au moins deux allocations (une pour l'objet
Tet une pour le bloc de contrôle du pointeur partagé), tandis que std :: make_shared < T > effectue généralement une seule allocation (la norme le recommande, mais ne l'exige pas ; toutes les implémentations connues le font). -
Si un
std::weak_ptr
référence le bloc de contrôle créé par
std::make_sharedaprès la fin de la durée de vie de tous les propriétaires partagés, la mémoire occupée parTpersiste jusqu'à ce que tous les propriétaires faibles soient également détruits, ce qui peut être indésirable si sizeof ( T ) est important. -
std::
shared_ptr
<
T
>
(
new T
(
args...
)
)
peut appeler un constructeur non public de
Ts'il est exécuté dans un contexte où il est accessible, tandis questd::make_sharednécessite un accès public au constructeur sélectionné. -
Contrairement aux constructeurs de
std::shared_ptr
,
std::make_sharedn'autorise pas de suppresseur personnalisé. -
std::make_sharedutilise :: new , donc si un comportement spécial a été configuré en utilisant un operator new spécifique à la classe, il différera de std:: shared_ptr < T > ( new T ( args... ) ) .
|
(jusqu'à C++20) |
|
(jusqu'à C++17) |
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.
| Macro de test de fonctionnalité | Valeur | Norme | Fonctionnalité |
|---|---|---|---|
__cpp_lib_shared_ptr_arrays
|
201707L
|
(C++20) |
Support des tableaux pour
std::make_shared
; surcharges
(
2-5
)
|
__cpp_lib_smart_ptr_for_overwrite
|
202002L
|
(C++20) |
Création de pointeurs intelligents avec initialisation par défaut (
std::allocate_shared_for_overwrite
,
std::make_shared_for_overwrite
,
std::make_unique_for_overwrite
); surcharges
(
6,7
)
|
Exemple
#include <iostream> #include <memory> #include <type_traits> #include <vector> struct C { // constructeurs nécessaires (jusqu'à C++20) C(int i) : i(i) {} C(int i, float f) : i(i), f(f) {} int i; float f{}; }; int main() { // utilisation de « auto » pour le type de « sp1 » auto sp1 = std::make_shared<C>(1); // surcharge (1) static_assert(std::is_same_v<decltype(sp1), std::shared_ptr<C>>); std::cout << "sp1->{ i:" << sp1->i << ", f:" << sp1->f << " }\n"; // être explicite avec le type de « sp2 » std::shared_ptr<C> sp2 = std::make_shared<C>(2, 3.0f); // surcharge (1) static_assert(std::is_same_v<decltype(sp2), std::shared_ptr<C>>); static_assert(std::is_same_v<decltype(sp1), decltype(sp2)>); std::cout << "sp2->{ i:" << sp2->i << ", f:" << sp2->f << " }\n"; // shared_ptr vers un float[64] initialisé par valeur ; surcharge (2): std::shared_ptr<float[]> sp3 = std::make_shared<float[]>(64); // shared_ptr vers un long[5][3][4] initialisé par valeur ; surcharge (2) : std::shared_ptr<long[][3][4]> sp4 = std::make_shared<long[][3][4]>(5); // shared_ptr vers un short[128] initialisé par valeur ; surcharge (3) : std::shared_ptr<short[128]> sp5 = std::make_shared<short[128]>(); // shared_ptr vers un int[7][6][5] initialisé par valeur ; surcharge (3) : std::shared_ptr<int[7][6][5]> sp6 = std::make_shared<int[7][6][5]>(); // shared_ptr vers un double[256], où chaque élément est 2.0 ; surcharge (4) : std::shared_ptr<double[]> sp7 = std::make_shared<double[]>(256, 2.0); // shared_ptr vers un double[7][2], où chaque double[2] // element est {3.0, 4.0}; surcharge (4): std::shared_ptr<double[][2]> sp8 = std::make_shared<double[][2]>(7, {3.0, 4.0}); // shared_ptr vers un vector<int>[4], où chaque vector // a pour contenu {5, 6}; surcharge (4) : std::shared_ptr<std::vector<int>[]> sp9 = std::make_shared<std::vector<int>[]>(4, {5, 6}); // shared_ptr vers un float[512], où chaque élément est 1.0 ; surcharge (5) : std::shared_ptr<float[512]> spA = std::make_shared<float[512]>(1.0); // shared_ptr vers un double[6][2], où chaque élément double[2] // est {1.0, 2.0}; surcharge (5): std::shared_ptr<double[6][2]> spB = std::make_shared<double[6][2]>({1.0, 2.0}); // shared_ptr vers un vector<int>[4], où chaque vector // a pour contenu {5, 6} ; surcharge (5) : std::shared_ptr<std::vector<int>[4]> spC = std::make_shared<std::vector<int>[4]>({5, 6}); }
Sortie :
sp1->{ i:1, f:0 }
sp2->{ i:2, f:3 }
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 tel que publié | Comportement corrigé |
|---|---|---|---|
| LWG 4024 | C++20 |
il n'était pas clair comment les objets construits dans
std::make_shared_for_overwrite
sont détruits
|
clarifié |
Voir aussi
construit un nouveau
shared_ptr
(fonction membre publique) |
|
|
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) |
|
(C++14)
(C++20)
|
crée un pointeur unique qui gère un nouvel objet
(modèle de fonction) |
|
fonctions d'allocation
(fonction) |