std:: allocate_shared, std:: allocate_shared_for_overwrite
|
Défini dans l'en-tête
<memory>
|
||
|
template
<
class
T,
class
Alloc,
class
...
Args
>
shared_ptr < T > allocate_shared ( const Alloc & alloc, Args && ... args ) ; |
(1) | (depuis C++11) |
|
template
<
class
T,
class
Alloc
>
shared_ptr < T > allocate_shared ( const Alloc & alloc, std:: size_t N ) ; |
(2) | (depuis C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr < T > allocate_shared ( const Alloc & alloc ) ; |
(3) | (depuis C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr
<
T
>
allocate_shared
(
const
Alloc
&
alloc,
std::
size_t
N,
|
(4) | (depuis C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr
<
T
>
allocate_shared
(
const
Alloc
&
alloc,
|
(5) | (depuis C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr < T > allocate_shared_for_overwrite ( const Alloc & alloc ) ; |
(6) | (depuis C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr
<
T
>
allocate_shared_for_overwrite
(
const
Alloc
&
alloc,
|
(7) | (depuis C++20) |
Alloue de la mémoire pour un objet en utilisant une copie de
alloc
(relié pour un
value_type
non spécifié) et initialise l'objet avec les arguments fournis. Retourne un objet
std::shared_ptr
gérant l'objet nouvellement créé.
T
, et est construit comme par
std::
allocator_traits
<
Alloc
>
::
construct
( a, pt, ( std:: forward < Args > ( args ) ... ) , où pt est un std:: remove_cv_t < T > * pointeur vers un espace de stockage adapté pour contenir un objet de type std:: remove_cv_t < T > . Si l'objet doit être détruit, il est détruit comme par std:: allocator_traits < Alloc > :: destroy ( a, pt ) , où pt est un pointeur vers cet objet de type std:: remove_cv_t < T > .
Alloc
, et c'est une copie potentiellement re-liée de
alloc
.
|
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
Dans la description ci-dessous,
a
est de type
Les éléments du tableau de type
2,3)
std::
allocator_traits
<
Alloc
>
::
construct
(
a, pu
)
4,5)
std::
allocator_traits
<
Alloc
>
::
construct
(
a, pu, 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
2-5)
std::
allocator_traits
<
Alloc
>
::
destroy
(
a, pu
)
, où
pu
est un pointeur
U
*
vers cet élément du tableau de type
U
6,7)
pu
-
>
~U
(
)
, où
pu
est un pointeur vers cet élément du tableau de type
U
|
(depuis C++20) |
Paramètres
| alloc | - | l' Allocator à utiliser |
| args... | - |
liste d'arguments avec lesquels une instance de
T
sera construite
|
| 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 les exceptions levées par
Alloc
::
allocate
(
)
ou par le constructeur de
T
. Si une exception est levée,
(1)
n'a 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.
Comme
std::make_shared
, cette fonction effectue généralement une seule allocation et place à la fois l'objet
T
et le bloc de contrôle dans le bloc de mémoire alloué (la norme recommande mais n'exige pas cela, toutes les implémentations connues le font). Une copie de
alloc
est stockée dans le bloc de contrôle afin de pouvoir être utilisée pour le désallouer une fois que les compteurs de références partagées et faibles atteignent zéro.
Contrairement aux
std::shared_ptr
constructors
,
std::allocate_shared
n'accepte pas de suppresseur personnalisé séparé : l'allocateur fourni est utilisé pour la destruction du bloc de contrôle et de l'objet
T
, ainsi que pour la désallocation de leur bloc de mémoire partagé.
|
std::shared_ptr
prend en charge les types tableau (depuis C++17), mais
|
(jusqu'à C++20) |
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 | Std | Fonctionnalité |
|---|---|---|---|
__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 <cstddef> #include <iostream> #include <memory> #include <memory_resource> #include <vector> class Value { int i; public: Value(int i) : i(i) { std::cout << "Value(), i = " << i << '\n'; } ~Value() { std::cout << "~Value(), i = " << i << '\n'; } void print() const { std::cout << "i = " << i << '\n'; } }; int main() { // Créer un allocateur polymorphe utilisant la ressource de tampon monotone std::byte buffer[sizeof(Value) * 8]; std::pmr::monotonic_buffer_resource resource(buffer, sizeof(buffer)); std::pmr::polymorphic_allocator<Value> allocator(&resource); std::vector<std::shared_ptr<Value>> v; for (int i{}; i != 4; ++i) // Utiliser std::allocate_shared avec l'allocateur personnalisé v.emplace_back(std::allocate_shared<Value>(allocator, i)); for (const auto& sp : v) sp->print(); } //< Tous les shared_ptr nettoieront automatiquement lorsqu'ils sortiront de la portée.
Sortie :
Value(), i = 0 Value(), i = 1 Value(), i = 2 Value(), i = 3 i = 0 i = 1 i = 2 i = 3 ~Value(), i = 0 ~Value(), i = 1 ~Value(), i = 2 ~Value(), i = 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 | Appliqué à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 3216 | C++20 |
std::allocate_shared
a toujours re-lié l'allocateur
avant de construire et détruire les objets |
le re-liage est optionnel |
| LWG 4024 | C++20 |
il n'était pas clair comment les objets construits dans
std::allocate_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
(fonction template) |