std::unique_ptr je inteligentný ukazovateľ predstavený v C++11. Automaticky spravuje dynamicky alokované zdroje na halde. Inteligentné ukazovatele sú len obaly okolo bežných starých ukazovateľov, ktoré vám pomáhajú predchádzať rozšíreným chybám. Konkrétne, zabudnutie vymazať ukazovateľ a spôsobiť únik pamäte alebo náhodné vymazanie ukazovateľa dvakrát alebo nesprávnym spôsobom. Môžu byť použité podobným spôsobom ako štandardné ukazovatele. Automatizujú niektoré manuálne procesy, ktoré spôsobujú bežné chyby.
Predpoklady: Ukazovateľ v C++ , Inteligentné ukazovatele v C++.
Syntax
unique_ptr< A>ptr1 (nové A )>
Tu,
- unique_ptr : Špecifikuje typ std::unique_ptr. V tomto prípade ide o objekt typu A.
- nový A : Objekt typu A je dynamicky alokovaný na halde pomocou operátora new.
- ptr1 : Toto je názov premennej std::unique_ptr.
Čo sa stane, keď sa použije unique_ptr?
Keď píšeme unique_ptr ptr1 (nové A), pamäť je alokovaná na halde pre inštanciu dátového typu A. ptr1 je inicializovaný a ukazuje na novovytvorený objekt A. Tu je ptr1 jediným vlastníkom novovytvoreného objektu A a spravuje životnosť tohto objektu. To znamená, že keď je ptr1 resetovaný alebo mimo rozsah, pamäť sa automaticky uvoľní a objekt A sa zničí.
Kedy použiť unique_ptr?
Keď sa vyžaduje vlastníctvo zdroja. Ak chceme jediné alebo výhradné vlastníctvo zdroja, mali by sme ísť po jedinečných ukazovateľoch. Len jeden jedinečný ukazovateľ môže ukazovať na jeden zdroj. Takže jeden jedinečný ukazovateľ nemožno skopírovať do iného. Tiež uľahčuje automatické čistenie, keď dynamicky alokované objekty prekročia rozsah, a pomáha predchádzať únikom pamäte.
Poznámka: Musíme použiť hlavičkový súbor na používanie týchto inteligentných ukazovateľov.
Príklady Unique_ptr
Príklad 1:
Vytvorme štruktúru A a tá bude mať metódu s názvom printA na zobrazenie nejakého textu. Potom v hlavnej časti vytvorme jedinečný ukazovateľ, ktorý bude ukazovať na štruktúru A. Takže v tomto bode máme inštanciu štruktúry A a p1 na ňu drží ukazovateľ.
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;> }> |
testovanie kompatibility
>
>Výkon
A struct.... 0x18dac20>
Príklad 2
Teraz vytvoríme ďalší ukazovateľ p2 a pokúsime sa skopírovať ukazovateľ p1 pomocou operátora priradenia (=).
C++
reťazec k itn
// 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;> }> |
>
>
Výkon
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; | ^~~~~~~~~~>
Vyššie uvedený kód spôsobí chybu v čase kompilácie, pretože nemôžeme priradiť ukazovateľ p2 k p1 v prípade jedinečných ukazovateľov. Na tento účel musíme použiť sémantiku pohybu, ako je uvedené nižšie.
orezanie reťazca javascript
Príklad 3
Správa objektu typu A pomocou sémantiky presunu.
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;> }> |
>
>Výkon
A struct.... 0x2018c20 A struct.... 0 0x2018c20>
Všimnite si, že keď sa adresa v ukazovateľovi p1 skopíruje do ukazovateľa p2, adresa ukazovateľa p1 sa zmení na NULL(0) a adresa uložená v p2 je teraz rovnaká ako adresa uložená v p1, čo znamená, že adresa v p1 bola prenesená do ukazovateľa p2 pomocou sémantiky pohybu.