std:: allocate_shared, std:: allocate_shared_for_overwrite
|
Definiert im Header
<memory>
|
||
|
template
<
class
T,
class
Alloc,
class
...
Args
>
shared_ptr < T > allocate_shared ( const Alloc & alloc, Args && ... args ) ; |
(1) | (seit C++11) |
|
template
<
class
T,
class
Alloc
>
shared_ptr < T > allocate_shared ( const Alloc & alloc, std:: size_t N ) ; |
(2) | (seit C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr < T > allocate_shared ( const Alloc & alloc ) ; |
(3) | (seit C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr
<
T
>
allocate_shared
(
const
Alloc
&
alloc,
std::
size_t
N,
|
(4) | (seit C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr
<
T
>
allocate_shared
(
const
Alloc
&
alloc,
|
(5) | (seit C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr < T > allocate_shared_for_overwrite ( const Alloc & alloc ) ; |
(6) | (seit C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr
<
T
>
allocate_shared_for_overwrite
(
const
Alloc
&
alloc,
|
(7) | (seit C++20) |
Reserviert Speicher für ein Objekt unter Verwendung einer Kopie von
alloc
(umgebunden für einen nicht spezifizierten
value_type
) und initialisiert das Objekt mit den bereitgestellten Argumenten. Gibt ein
std::shared_ptr
-Objekt zurück, das das neu erstellte Objekt verwaltet.
T
und wird konstruiert als ob durch
std::
allocator_traits
<
Alloc
>
::
construct
( a, pt, ( std:: forward < Args > ( args ) ... ) , wobei pt ein std:: remove_cv_t < T > * Zeiger auf Speicher ist, der für ein Objekt vom Typ std:: remove_cv_t < T > geeignet ist. Wenn das Objekt zerstört werden soll, wird es zerstört als ob durch std:: allocator_traits < Alloc > :: destroy ( a, pt ) , wobei pt ein Zeiger auf dieses Objekt vom Typ std:: remove_cv_t < T > ist.
Alloc
und stellt eine möglicherweise rebound Kopie von
alloc
dar.
|
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn
|
(since C++20) |
T
ein unbounded array type ist.
T
. Jedes Element hat einen Standardinitialwert.
T
ein bounded array type ist.
T
ein unbounded array type ist.
T
. Jedes Element hat den Anfangswert
u
.
T
ein bounded array type ist.
T
.
-
Wenn
Tkein Array-Typ ist, wird das Objekt konstruiert wie durch :: new ( pv ) T , wobei pv ein void * -Zeiger auf Speicher ist, der für ein Objekt vom TypTgeeignet ist. Wenn das Objekt zerstört werden soll, wird es zerstört wie durch pt - > ~T ( ) , wobei pt ein Zeiger auf dieses Objekt vom TypTist. -
Wenn
Tein Array-Typ mit fester Größe ist, ist der Anfangswert für jedes Element nicht spezifiziert.
T
kein Array-Typ ist oder ein Array-Typ mit fester Größe ist.
T
ein unbounded array type ist.
Initialisierung und Zerstörung von Array-Elementen
In der folgenden Beschreibung ist
a
vom Typ
Array-Elemente vom Typ
2,3)
std::
allocator_traits
<
Alloc
>
::
construct
(
a, pu
)
4,5)
std::
allocator_traits
<
Alloc
>
::
construct
(
a, pu, u
)
6,7)
::
new
(
pv
)
U
Wenn die Lebensdauer des durch den zurückgegebenen std::shared_ptr verwalteten Objekts endet oder wenn die Initialisierung eines Array-Elements eine Ausnahme auslöst, werden die initialisierten Elemente in umgekehrter Reihenfolge ihrer ursprünglichen Konstruktion zerstört.
Für jedes zu zerstörende Array-Element vom Nicht-Array-Typ
2-5)
std::
allocator_traits
<
Alloc
>
::
destroy
(
a, pu
)
, wobei
pu
ein
U
*
Zeiger auf dieses Array-Element vom Typ
U
ist
6,7)
pu
-
>
~U
(
)
, wobei
pu
ein Zeiger auf dieses Array-Element vom Typ
U
ist
|
(seit C++20) |
Parameter
| alloc | - | der Allocator der verwendet werden soll |
| args... | - |
Liste der Argumente, mit denen eine Instanz von
T
konstruiert wird
|
| N | - | die zu verwendende Array-Größe |
| u | - | der Initialwert, mit dem jedes Element des Arrays initialisiert wird |
Rückgabewert
std::shared_ptr
zu einem Objekt vom Typ
T
oder
std::
remove_extent_t
<
T
>
[
N
]
falls
T
ein unbegannter Array-Typ ist
(seit C++20)
.
Für den zurückgegebenen std::shared_ptr r gibt r. get ( ) einen nicht-null Zeiger zurück und r. use_count ( ) gibt 1 zurück.
Exceptions
Kann die Ausnahmen werfen, die von
Alloc
::
allocate
(
)
oder vom Konstruktor von
T
geworfen werden. Wenn eine Ausnahme geworfen wird,
(1)
hat keine Wirkung.
Wenn eine Ausnahme während der Konstruktion des Arrays geworfen wird, werden bereits initialisierte Elemente in umgekehrter Reihenfolge zerstört
(since C++20)
.
Hinweise
Diese Funktionen werden typischerweise mehr Speicher allokieren als sizeof ( T ) , um Platz für interne Verwaltungsstrukturen wie Referenzzähler zu ermöglichen.
Wie
std::make_shared
führt diese Funktion typischerweise nur eine Speicherallokation durch und platziert sowohl das
T
-Objekt als auch den Kontrollblock im allozierten Speicherblock (der Standard empfiehlt dies, schreibt es aber nicht vor, alle bekannten Implementierungen tun dies). Eine Kopie von
alloc
wird als Teil des Kontrollblocks gespeichert, damit sie zur Freigabe verwendet werden kann, sobald sowohl die shared- als auch weak-Referenzzähler null erreichen.
Im Gegensatz zu den
std::shared_ptr
constructors
akzeptiert
std::allocate_shared
keinen separaten benutzerdefinierten Deleter: Der bereitgestellte Allokator wird für die Zerstörung des Kontrollblocks und des
T
-Objekts sowie für die Freigabe ihres gemeinsamen Speicherblocks verwendet.
|
std::shared_ptr
unterstützt Array-Typen (seit C++17), aber
|
(bis C++20) |
Ein Konstruktor
aktiviert
shared_from_this
mit einem Zeiger
ptr
vom Typ
U*
bedeutet, dass er bestimmt, ob
U
eine
eindeutige und zugängliche
(seit C++17)
Basisklasse besitzt, die eine Spezialisierung von
std::enable_shared_from_this
ist, und falls ja, wertet der Konstruktor
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
)
)
;
aus.
Die Zuweisung an
weak_this
ist nicht atomar und steht in Konflikt mit jedem potenziell gleichzeitigen Zugriff auf dasselbe Objekt. Dies stellt sicher, dass zukünftige Aufrufe von
shared_from_this()
den Besitz mit dem
std::shared_ptr
teilen, der durch diesen Rohzeiger-Konstruktor erstellt wurde.
Der Test
ptr
-
>
weak_this
.
expired
(
)
im obigen Code stellt sicher, dass
weak_this
nicht neu zugewiesen wird, falls es bereits auf einen Besitzer verweist. Dieser Test ist ab C++17 erforderlich.
| Feature-Test Makro | Wert | Std | Funktion |
|---|---|---|---|
__cpp_lib_smart_ptr_for_overwrite
|
202002L
|
(C++20) |
Smart-Pointer-Erstellung mit Standardinitialisierung (
std::allocate_shared_for_overwrite
,
std::make_shared_for_overwrite
,
std::make_unique_for_overwrite
); Überladungen
(
6,7
)
|
Beispiel
#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() { // Erstellen eines polymorphen Allokators mit der monotonen Pufferressource 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) // Verwenden von std::allocate_shared mit dem benutzerdefinierten Allokator v.emplace_back(std::allocate_shared<Value>(allocator, i)); for (const auto& sp : v) sp->print(); } //< Alle Shared Pointer werden automatisch bereinigt, wenn sie den Gültigkeitsbereich verlassen.
Ausgabe:
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
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 3216 | C++20 |
std::allocate_shared
hat den Allokator immer
vor Objektkonstruktion und -zerstörung reboundet |
Rebind ist optional |
| LWG 4024 | C++20 |
es war unklar, wie die in
std::allocate_shared_for_overwrite
konstruierten Objekte zerstört werden
|
klargestellt |
Siehe auch
Konstruiert neuen
shared_ptr
(öffentliche Elementfunktion) |
|
|
Erstellt einen Shared Pointer, der ein neues Objekt verwaltet
(Funktionstemplate) |