std::unique_ptr ist ein intelligenter Zeiger, der in C++11 eingeführt wurde. Es verwaltet automatisch die dynamisch zugewiesenen Ressourcen auf dem Heap. Intelligente Zeiger sind lediglich Wrapper um normale alte Zeiger, die Ihnen helfen, weit verbreitete Fehler zu verhindern. Nämlich das Vergessen, einen Zeiger zu löschen und einen Speicherverlust zu verursachen, oder das versehentliche zweimalige oder falsche Löschen eines Zeigers. Sie können auf ähnliche Weise wie Standardzeiger verwendet werden. Sie automatisieren einige der manuellen Prozesse, die häufige Fehler verursachen.
Voraussetzungen: Zeiger in C++ , Intelligente Zeiger in C++.
Syntax
unique_ptr< A>ptr1 (neues A )>
Hier,
- unique_ptr : Es gibt den Typ des std::unique_ptr an. In diesem Fall ein Objekt vom Typ A.
- neu A : Ein Objekt vom Typ A wird mithilfe des neuen Operators dynamisch auf dem Heap zugewiesen.
- ptr1 : Dies ist der Name der Variablen std::unique_ptr.
Was passiert, wenn unique_ptr verwendet wird?
Wenn wir unique_ptr schreiben ptr1 (neues A): Speicher wird auf dem Heap für eine Instanz des Datentyps A zugewiesen. ptr1 wird initialisiert und zeigt auf das neu erstellte A-Objekt. Hier ist ptr1 der einzige Besitzer des neu erstellten Objekts A und verwaltet die Lebensdauer dieses Objekts. Dies bedeutet, dass, wenn ptr1 zurückgesetzt wird oder den Gültigkeitsbereich verlässt, die Speicherzuordnung automatisch aufgehoben wird und das Objekt von A zerstört wird.
Wann sollte unique_ptr verwendet werden?
Wenn der Besitz einer Ressource erforderlich ist. Wenn wir den alleinigen oder exklusiven Besitz einer Ressource wünschen, sollten wir uns für eindeutige Zeiger entscheiden. Nur ein eindeutiger Zeiger kann auf eine Ressource verweisen. Daher kann ein eindeutiger Zeiger nicht auf einen anderen kopiert werden. Außerdem erleichtert es die automatische Bereinigung, wenn dynamisch zugewiesene Objekte den Gültigkeitsbereich verlassen, und hilft, Speicherlecks zu verhindern.
Hinweis: Wir müssen das verwenden Header-Datei zur Verwendung dieser intelligenten Zeiger.
Beispiele für Unique_ptr
Beispiel 1:
Erstellen wir eine Struktur A und sie verfügt über eine Methode namens printA, um Text anzuzeigen. Dann erstellen wir im Hauptabschnitt einen eindeutigen Zeiger, der auf die Struktur A zeigt. An diesem Punkt haben wir also eine Instanz der Struktur A und p1 enthält den Zeiger darauf.
C++
// C++ Program to implement unique_ptr> #include> #include> using> namespace> std;> > struct> A {> >void> printA() { cout <<>'A struct....'> << endl; }> };> > int> main()> {> >unique_ptr p1(> new> A);> >p1->printA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> >return> 0;> }> |
Linksverknüpfung vs. Rechtsverknüpfung
>
>Ausgabe
A struct.... 0x18dac20>
Beispiel 2
Jetzt erstellen wir einen weiteren Zeiger p2 und versuchen, den Zeiger p1 mithilfe des Zuweisungsoperators (=) zu kopieren.
C++
// C++ Program to implement unique_ptr> #include> #include> using> namespace> std;> > struct> A {> >void> printA() { cout <<>'A struct....'> << endl; }> };> int> main()> {> >unique_ptr p1(> new> A);> >p1->printA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> > >// will give compile time error> >unique_ptr> p2 = p1;> >p2->printA();> >return> 0;> }> |
Marquee-HTML
>
>
Ausgabe
main.cpp: In function ‘int main()’: main.cpp:18:24: error: use of deleted function ‘std::unique_ptr::unique_ptr(const std::unique_ptr&) [with _Tp = A; _Dp = std::default_delete]’ 18 | unique_ptr p2 = p1; | ^~ In file included from /usr/include/c++/11/memory:76, from main.cpp:3: /usr/include/c++/11/bits/unique_ptr.h:468:7: note: declared here 468 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~>
Der obige Code führt zu einem Fehler bei der Kompilierung, da wir bei eindeutigen Zeigern den Zeiger p2 nicht auf p1 zuweisen können. Wir müssen die Bewegungssemantik für diesen Zweck verwenden, wie unten gezeigt.
cast sql
Beispiel 3
Verwalten eines Objekts vom Typ A mithilfe der Verschiebungssemantik.
C++
// C++ Program to implement unique_ptr> #include> #include> using> namespace> std;> > struct> A {> >void> printA() { cout <<>'A struct....'> << endl; }> };> int> main()> {> >unique_ptr p1(> new> A);> >p1->printA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> > >// now address stored in p1 shpould get copied to p2> >unique_ptr> p2 = move(p1);> > >p2->printA();> >cout << p1.get() << endl;> >cout << p2.get() << endl;> >return> 0;> }> |
>
>Ausgabe
A struct.... 0x2018c20 A struct.... 0 0x2018c20>
Beachten Sie, dass, sobald die Adresse in Zeiger p1 in Zeiger p2 kopiert wird, die Adresse von Zeiger p1 NULL(0) wird und die von p2 gespeicherte Adresse nun mit der von p1 gespeicherten Adresse übereinstimmt. Dies zeigt, dass die Adresse in p1 an den Zeiger übertragen wurde p2 unter Verwendung der Bewegungssemantik.