Der Konstruktor von unique_ptr<T>
akzeptiert einen Rohzeiger auf ein Objekt vom Typ T
(also akzeptiert er a T*
).
Im ersten Beispiel:
unique_ptr<int> uptr (new int(3));
Der Zeiger ist das Ergebnis eines new
Ausdrucks, während im zweiten Beispiel:
unique_ptr<double> uptr2 (pd);
Der Zeiger wird in der pd
Variablen gespeichert .
Konzeptionell ändert sich nichts (Sie konstruieren einen unique_ptr
aus einem Rohzeiger), aber der zweite Ansatz ist möglicherweise gefährlicher, da Sie beispielsweise Folgendes tun könnten:
unique_ptr<double> uptr2 (pd);
// ...
unique_ptr<double> uptr3 (pd);
Somit gibt es zwei eindeutige Zeiger, die dasselbe Objekt effektiv einkapseln (wodurch die Semantik eines eindeutigen Zeigers verletzt wird ).
Aus diesem Grund ist das erste Formular zum Erstellen eines eindeutigen Zeigers nach Möglichkeit besser. Beachten Sie, dass wir in C ++ 14 Folgendes tun können:
unique_ptr<int> p = make_unique<int>(42);
Welches ist klarer und sicherer. Nun zu Ihrem Zweifel:
Was mir auch nicht klar ist, ist, wie sich auf diese Weise deklarierte Zeiger von den auf "normale" Weise deklarierten Zeigern unterscheiden.
Intelligente Zeiger sollen den Objektbesitz modellieren und automatisch dafür sorgen, dass das spitze Objekt zerstört wird, wenn der letzte (intelligente, besitzende) Zeiger auf dieses Objekt außerhalb des Gültigkeitsbereichs liegt.
Auf diese Weise müssen Sie sich nicht daran erinnern, dass Sie delete
Objekte dynamisch zugewiesen haben - der Destruktor des intelligenten Zeigers erledigt dies für Sie - und Sie müssen sich auch keine Gedanken darüber machen, ob Sie einen (baumelnden) Zeiger nicht auf ein bereits zerstörtes Objekt dereferenzieren:
{
unique_ptr<int> p = make_unique<int>(42);
// Going out of scope...
}
// I did not leak my integer here! The destructor of unique_ptr called delete
Jetzt unique_ptr
handelt es sich um einen intelligenten Zeiger, der die eindeutige Eigentümerschaft modelliert. Dies bedeutet, dass zu jedem Zeitpunkt in Ihrem Programm nur ein (besitzender) Zeiger auf das spitze Objekt vorhanden sein darf - daher kann er unique_ptr
nicht kopiert werden.
Solange Sie Smart Pointer so verwenden, dass der implizite Vertrag, den Sie einhalten müssen, nicht verletzt wird, haben Sie die Garantie, dass kein Speicher verloren geht, und die ordnungsgemäße Eigentumsrichtlinie für Ihr Objekt wird durchgesetzt. Rohe Zeiger geben Ihnen diese Garantie nicht.
new int(3)
Gibt einen Zeiger auf das Neue zurückint
, genau wiepd
ein Zeiger auf das Neuedouble
.