std::unique_ptr è un puntatore intelligente introdotto in C++11. Gestisce automaticamente le risorse allocate dinamicamente sull'heap. I puntatori intelligenti sono solo degli involucri attorno ai vecchi puntatori regolari che ti aiutano a prevenire bug diffusi. Vale a dire, dimenticare di eliminare un puntatore e causare una perdita di memoria o eliminare accidentalmente un puntatore due volte o nel modo sbagliato. Possono essere utilizzati in modo simile ai puntatori standard. Automatizzano alcuni dei processi manuali che causano bug comuni.
Prerequisiti: Puntatore in C++ , Puntatori intelligenti in C++.
Sintassi
unique_ptr< A>ptr1 (nuovo A )>
Qui,
- unique_ptr : Specifica il tipo di std::unique_ptr. In questo caso- un oggetto di tipo A.
- nuova A : Un oggetto di tipo A viene allocato dinamicamente sull'heap utilizzando l'operatore new.
- ptr1 : Questo è il nome della variabile std::unique_ptr.
Cosa succede quando viene utilizzato unique_ptr?
Quando scriviamo unique_ptr ptr1 (nuovo A), la memoria viene allocata sull'heap per un'istanza del tipo di dati A. ptr1 viene inizializzato e punta all'oggetto A appena creato. Qui, ptr1 è l'unico proprietario dell'oggetto A appena creato e gestisce la durata di questo oggetto. Ciò significa che quando ptr1 viene reimpostato o esce dall'ambito, la memoria viene automaticamente deallocata e l'oggetto di A viene distrutto.
Quando utilizzare unique_ptr?
Quando è richiesta la proprietà della risorsa. Quando vogliamo la proprietà singola o esclusiva di una risorsa, allora dovremmo optare per puntatori univoci. Solo un puntatore univoco può puntare a una risorsa. Pertanto, un puntatore univoco non può essere copiato su un altro. Inoltre, facilita la pulizia automatica quando gli oggetti allocati dinamicamente escono dall'ambito e aiuta a prevenire perdite di memoria.
Nota: dobbiamo utilizzare il file file di intestazione per l'utilizzo di questi puntatori intelligenti.
Esempi di Unique_ptr
Esempio 1:
Creiamo una struttura A e avrà un metodo chiamato printA per visualizzare del testo. Quindi, nella sezione principale, creiamo un puntatore univoco che punterà alla struttura A. Quindi, a questo punto, abbiamo un'istanza della struttura A e p1 contiene il puntatore a quella.
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->stampaA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> >return> 0;> }> |
ordinamento di fusione
>
>Produzione
A struct.... 0x18dac20>
Esempio 2
Ora creiamo un altro puntatore p2 e proveremo a copiare il puntatore p1 utilizzando l'operatore di assegnazione(=).
C++
modello ip tcp
// 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->stampaA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> > >// will give compile time error> >unique_ptr> p2 = p1;> >p2->stampaA();> >return> 0;> }> |
>
>
Produzione
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; | ^~~~~~~~~~>
Il codice precedente fornirà un errore in fase di compilazione poiché non possiamo assegnare il puntatore da p2 a p1 in caso di puntatori univoci. Dobbiamo utilizzare la semantica di spostamento per tale scopo, come mostrato di seguito.
convertire nfa in dfa
Esempio 3
Gestione dell'oggetto di tipo A utilizzando la semantica di spostamento.
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->stampaA();> > >// 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->stampaA();> >cout << p1.get() << endl;> >cout << p2.get() << endl;> >return> 0;> }> |
>
>Produzione
A struct.... 0x2018c20 A struct.... 0 0x2018c20>
Nota una volta che l'indirizzo nel puntatore p1 viene copiato nel puntatore p2, l'indirizzo del puntatore p1 diventa NULL(0) e l'indirizzo memorizzato da p2 è ora lo stesso dell'indirizzo memorizzato da p1, mostrando che l'indirizzo in p1 è stato trasferito al puntatore p2 utilizzando la semantica di spostamento.