Namespaces
Variants

std:: allocate_shared, std:: allocate_shared_for_overwrite

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
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,

const std:: remove_extent_t < T > & u ) ;
(4) (seit C++20)
template < class T, class Alloc >

shared_ptr < T > allocate_shared ( const Alloc & alloc,

const std:: remove_extent_t < T > & u ) ;
(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,

std:: size_t N ) ;
(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.

1) Das Objekt ist vom Typ 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.
In der obigen Beschreibung ist a vom Typ Alloc und stellt eine möglicherweise rebound Kopie von alloc dar.

Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn T kein Array-Typ ist.

(since C++20)
2) Das Objekt ist vom Typ std:: remove_extent_t < T > [ N ] . Jedes Element hat einen Standard-Initialwert.
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn T ein unbounded array type ist.
3) Das Objekt ist vom Typ T . Jedes Element hat einen Standardinitialwert.
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn T ein bounded array type ist.
4) Das Objekt ist vom Typ std:: remove_extent_t < T > [ N ] . Jedes Element hat den Anfangswert u .
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn T ein unbounded array type ist.
5) Das Objekt ist vom Typ T . Jedes Element hat den Anfangswert u .
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn T ein bounded array type ist.
6) Das Objekt ist vom Typ T .
  • Wenn T kein 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 Typ T geeignet ist. Wenn das Objekt zerstört werden soll, wird es zerstört wie durch pt - > ~T ( ) , wobei pt ein Zeiger auf dieses Objekt vom Typ T ist.
  • Wenn T ein Array-Typ mit fester Größe ist, ist der Anfangswert für jedes Element nicht spezifiziert.
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn T kein Array-Typ ist oder ein Array-Typ mit fester Größe ist.
7) Das Objekt ist vom Typ std:: remove_extent_t < T > [ N ] . Der Anfangswert ist für jedes Element nicht spezifiziert.
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn T ein unbounded array type ist.

Inhaltsverzeichnis

Initialisierung und Zerstörung von Array-Elementen

In der folgenden Beschreibung ist a vom Typ Alloc und stellt eine möglicherweise rebound Kopie von alloc dar.

Array-Elemente vom Typ U werden in aufsteigender Reihenfolge ihrer Adressen initialisiert.

  • Wenn U kein Array-Typ ist, wird jedes Element konstruiert, als ob durch den folgenden Ausdruck, wobei pu ein std:: remove_cv_t < U > * Zeiger auf Speicher ist, der für ein Objekt vom Typ std:: remove_cv_t < U > geeignet ist, und pv ein void * Zeiger auf Speicher ist, der für ein Objekt vom Typ U geeignet ist:
2,3) std:: allocator_traits < Alloc > :: construct ( a, pu )
4,5) std:: allocator_traits < Alloc > :: construct ( a, pu, u )
6,7) :: new ( pv ) U
  • Andernfalls werden die Elemente jedes Elements rekursiv initialisiert. Für die nächste Dimension:

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 U wird es wie durch den folgenden Ausdruck zerstört:

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 std::allocate_shared nicht. Diese Funktionalität wird durch boost::allocate_shared bereitgestellt.

(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)