std::unique_ptr<T,Deleter>:: unique_ptr
|
Mitglieder der primären Template, unique_ptr<T>
|
||
|
constexpr
unique_ptr
(
)
noexcept
;
constexpr unique_ptr ( std:: nullptr_t ) noexcept ; |
(1) | |
|
explicit
unique_ptr
(
pointer p
)
noexcept
;
|
(2) | (constexpr seit C++23) |
|
unique_ptr
(
pointer p,
/* siehe unten */
d1
)
noexcept
;
|
(3) | (constexpr seit C++23) |
|
unique_ptr
(
pointer p,
/* siehe unten */
d2
)
noexcept
;
|
(4) | (constexpr seit C++23) |
|
unique_ptr
(
unique_ptr
&&
u
)
noexcept
;
|
(5) | (constexpr seit C++23) |
|
template
<
class
U,
class
E
>
unique_ptr ( unique_ptr < U, E > && u ) noexcept ; |
(6) | (constexpr seit C++23) |
|
unique_ptr
(
const
unique_ptr
&
)
=
delete
;
|
(7) | |
|
template
<
class
U
>
unique_ptr ( std:: auto_ptr < U > && u ) noexcept ; |
(8) | (entfernt in C++17) |
|
Mitglieder der Spezialisierung für Arrays, unique_ptr<T[]>
|
||
|
constexpr
unique_ptr
(
)
noexcept
;
constexpr unique_ptr ( std:: nullptr_t ) noexcept ; |
(1) | |
|
template
<
class
U
>
explicit unique_ptr ( U p ) noexcept ; |
(2) | (constexpr seit C++23) |
|
template
<
class
U
>
unique_ptr ( U p, /* siehe unten */ d1 ) noexcept ; |
(3) | (constexpr seit C++23) |
|
template
<
class
U
>
unique_ptr ( U p, /* siehe unten */ d2 ) noexcept ; |
(4) | (constexpr seit C++23) |
|
unique_ptr
(
unique_ptr
&&
u
)
noexcept
;
|
(5) | (constexpr seit C++23) |
|
template
<
class
U,
class
E
>
unique_ptr ( unique_ptr < U, E > && u ) noexcept ; |
(6) | (constexpr seit C++23) |
|
unique_ptr
(
const
unique_ptr
&
)
=
delete
;
|
(7) | |
std::unique_ptr
der nichts besitzt. Wertinitialisiert den gespeicherten Zeiger und den gespeicherten Deleter. Erfordert, dass
Deleter
DefaultConstructible
ist und dass die Konstruktion keine Ausnahme wirft. Diese Überladungen nehmen nur dann an der Überladungsauflösung teil, wenn
std::
is_default_constructible
<
Deleter
>
::
value
true
ist und
Deleter
kein Zeigertyp ist.
std::unique_ptr
, der
p
besitzt, initialisiert den gespeicherten Zeiger mit
p
und wertinitialisiert den gespeicherten Deleter. Erfordert, dass
Deleter
DefaultConstructible
ist und dass die Konstruktion keine Ausnahme auslöst. Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn
std::
is_default_constructible
<
Deleter
>
::
value
true
ist und
Deleter
kein Zeigertyp ist.
|
Dieser Konstruktor wird nicht durch Class Template Argument Deduction ausgewählt. |
(seit C++17) |
std::unique_ptr
-Objekt, das
p
besitzt, initialisiert den gespeicherten Zeiger mit
p
und initialisiert einen Deleter
D
wie folgt (hängt davon ab, ob
D
ein Referenztyp ist).
D
ein Nicht-Referenztyp
A
ist, dann sind die Signaturen:
|
unique_ptr
(
pointer p,
const
A
&
d
)
noexcept
;
|
(1) |
(erfordert, dass
Deleter
nothrow-
CopyConstructible
ist)
|
|
unique_ptr
(
pointer p, A
&&
d
)
noexcept
;
|
(2) |
(erfordert, dass
Deleter
nothrow-
MoveConstructible
ist)
|
D
ein Lvalue-Referenztyp
A
&
ist, dann lauten die Signaturen:
|
unique_ptr
(
pointer p, A
&
d
)
noexcept
;
|
(1) | |
|
unique_ptr
(
pointer p, A
&&
d
)
=
delete
;
|
(2) | |
D
ein Lvalue-Referenztyp
const
A
&
ist, dann lauten die Signaturen:
|
unique_ptr
(
pointer p,
const
A
&
d
)
noexcept
;
|
(1) | |
|
unique_ptr
(
pointer p,
const
A
&&
d
)
=
delete
;
|
(2) | |
|
Diese beiden Konstruktoren werden nicht durch Klassen-Template-Argument-Deduktion ausgewählt. |
(seit C++17) |
-
Uist der gleiche Typ wiepointer, oder -
Uist std::nullptr_t , oder -
pointerist der gleiche Typ wieelement_type*undUist ein ZeigertypV*, sodassV(*)[]implizit konvertierbar zuelement_type(*)[]ist.
unique_ptr
durch Übertragung des Besitzes von
u
an
*
this
und speichert den Nullzeiger in
u
. Dieser Konstruktor nimmt nur an der Überladungsauflösung teil, wenn
std::
is_move_constructible
<
Deleter
>
::
value
gleich
true
ist. Wenn
Deleter
kein Referenztyp ist, erfordert dies, dass es nothrow-
MoveConstructible
ist (wenn
Deleter
eine Referenz ist, verweisen
get_deleter()
und
u.get_deleter()
nach der Move-Konstruktion auf denselben Wert).
unique_ptr
durch Übertragung des Besitzes von
u
an
*
this
, wobei
u
mit einem spezifizierten Deleter (
E
) konstruiert wird. Es hängt davon ab, ob
E
ein Referenztyp ist, wie folgt:
E
ein Referenztyp ist, wird dieser Deleter aus
u
's Deleter kopierkonstruiert (erfordert, dass diese Konstruktion keine Ausnahme wirft),
E
ein Nicht-Referenztyp ist, wird dieser Deleter aus
u
's Deleter move-konstruiert (erfordert, dass diese Konstruktion keine Ausnahme wirft).
pointer
,
Deleter
ein Referenztyp und
E
ist vom gleichen Typ wie
Deleter
, oder
Deleter
ist kein Referenztyp und
E
ist implizit konvertierbar zu
Deleter
.
-
Uist ein Array-Typ, -
pointerist vom gleichen Typ wieelement_type*, - unique_ptr < U,E > :: pointer ist vom gleichen Typ wie unique_ptr < U,E > :: element_type * ,
-
unique_ptr
<
U,E
>
::
element_type
(
*
)
[
]
ist konvertierbar zu
element_type(*)[], -
entweder
Deleterist ein Referenztyp undEist vom gleichen Typ wieDeleter, oderDeleterist kein Referenztyp undEist implizit konvertierbar zuDeleter.
unique_ptr
, bei dem der gespeicherte Zeiger mit
u.release()
initialisiert wird und der gespeicherte Deleter wertinitialisiert ist. Dieser Konstruktor nimmt nur an der Überladungsauflösung teil, wenn
U*
implizit in
T*
konvertierbar ist und
Deleter
denselben Typ wie
std::
default_delete
<
T
>
besitzt.
Inhaltsverzeichnis |
Parameter
| p | - | ein Zeiger auf ein zu verwaltendes Objekt |
| d1, d2 | - | ein Deleter zur Zerstörung des Objekts |
| u | - | ein weiterer Smart Pointer, von dem der Besitz übernommen wird |
Hinweise
|
Anstatt die Überladung (2) zusammen mit new zu verwenden, ist es oft besser, std::make_unique<T> zu verwenden. |
(since C++14) |
std:: unique_ptr < Derived > ist implizit konvertierbar zu std:: unique_ptr < Base > durch Überladung (6) (da sowohl der verwaltete Zeiger als auch std::default_delete implizit konvertierbar sind).
Da der Standardkonstruktor constexpr ist, werden statische unique_ptrs als Teil der statischen Nicht-Lokalen Initialisierung initialisiert, bevor jegliche dynamische Nicht-Lokale Initialisierung beginnt. Dies macht es sicher, einen unique_ptr im Konstruktor eines beliebigen statischen Objekts zu verwenden.
|
Es gibt keine Klassentemplate-Argumentableitung von Zeigertypen, da es unmöglich ist, zwischen einem Zeiger aus Array- und Nicht-Array-Formen von new zu unterscheiden. |
(seit C++17) |
Beispiel
#include <iostream> #include <memory> struct Foo // Objekt zur Verwaltung { Foo() { std::cout << "Foo Konstruktor\n"; } Foo(const Foo&) { std::cout << "Foo Kopierkonstruktor\n"; } Foo(Foo&&) { std::cout << "Foo Move-Konstruktor\n"; } ~Foo() { std::cout << "~Foo Destruktor\n"; } }; struct D // Deleter { D() {}; D(const D&) { std::cout << "D Kopierkonstruktor\n"; } D(D&) { std::cout << "D nicht-konstante Kopierkonstruktor\n"; } D(D&&) { std::cout << "D Move-Konstruktor \n"; } void operator()(Foo* p) const { std::cout << "D löscht ein Foo\n"; delete p; }; }; int main() { std::cout << "Beispiel Konstruktor(1)...\n"; std::unique_ptr<Foo> up1; // up1 ist leer std::unique_ptr<Foo> up1b(nullptr); // up1b ist leer std::cout << "Beispiel Konstruktor(2)...\n"; { std::unique_ptr<Foo> up2(new Foo); //up2 besitzt jetzt ein Foo } // Foo gelöscht std::cout << "Beispiel Konstruktor(3)...\n"; D d; { // Deleter-Typ ist keine Referenz std::unique_ptr<Foo, D> up3(new Foo, d); // Deleter kopiert } { // Deleter-Typ ist eine Referenz std::unique_ptr<Foo, D&> up3b(new Foo, d); // up3b enthält eine Referenz auf d } std::cout << "Beispiel Konstruktor(4)...\n"; { // deleter ist keine Referenz std::unique_ptr<Foo, D> up4(new Foo, D()); // deleter moved } std::cout << "Beispiel Konstruktor(5)...\n"; { std::unique_ptr<Foo> up5a(new Foo); std::unique_ptr<Foo> up5b(std::move(up5a)); // Eigentumsübertragung } std::cout << "Beispiel Konstruktor(6)...\n"; { std::unique_ptr<Foo, D> up6a(new Foo, d); // D wird kopiert std::unique_ptr<Foo, D> up6b(std::move(up6a)); // D wird verschoben std::unique_ptr<Foo, D&> up6c(new Foo, d); // D ist eine Referenz std::unique_ptr<Foo, D> up6d(std::move(up6c)); // D wird kopiert } #if (__cplusplus < 201703L) std::cout << "Beispiel Konstruktor(7)...\n"; { std::auto_ptr<Foo> up7a(new Foo); std::unique_ptr<Foo> up7b(std::move(up7a)); // Eigentumsübertragung } #endif std::cout << "Beispiel Array-Konstruktor...\n"; { std::unique_ptr<Foo[]> up(new Foo[3]); } // drei Foo-Objekte gelöscht }
Ausgabe:
Beispiel Konstruktor(1)... Beispiel Konstruktor(2)... Foo ctor ~Foo dtor Beispiel Konstruktor(3)... Foo ctor D copy ctor D löscht ein Foo ~Foo dtor Foo ctor D löscht ein Foo ~Foo dtor Beispiel Konstruktor(4)... Foo ctor D move ctor D löscht ein Foo ~Foo dtor Beispiel Konstruktor(5)... Foo ctor ~Foo dtor Beispiel Konstruktor(6)... Foo ctor D copy ctor D move ctor Foo ctor D non-const copy ctor D löscht ein Foo ~Foo dtor D löscht ein Foo ~Foo dtor Beispiel Konstruktor(7)... Foo ctor ~Foo dtor Beispiel Array-Konstruktor... Foo ctor Foo ctor Foo ctor ~Foo dtor ~Foo dtor ~Foo dtor
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 2118 | C++11 |
Konstruktoren von
unique_ptr<T[]>
lehnten Qualifikationskonvertierungen ab.
|
Akzeptiert. |
| LWG 2520 | C++11 |
unique_ptr<T[]>
wurde versehentlich nicht-konstruierbar von
nullptr_t
gemacht.
|
Konstruierbar gemacht. |
| LWG 2801 | C++11 | Der Standardkonstruktor war nicht eingeschränkt. | Eingeschränkt. |
| LWG 2899 | C++11 | Der Move-Konstruktor war nicht eingeschränkt. | Eingeschränkt. |
| LWG 2905 | C++11 | Einschränkung des Konstruktors von einem Zeiger und einem Deleter war falsch. | Korrigiert. |
| LWG 2944 | C++11 | Einige Vorbedingungen wurden versehentlich durch LWG 2905 entfernt | Wiederhergestellt. |