std::unique_ptr je chytrý ukazatel představený v C++11. Automaticky spravuje dynamicky alokované zdroje na haldě. Inteligentní ukazatele jsou jen obaly kolem běžných starých ukazatelů, které vám pomáhají předcházet rozšířeným chybám. Konkrétně zapomenutí smazat ukazatel a způsobit únik paměti nebo náhodné smazání ukazatele dvakrát nebo nesprávným způsobem. Lze je použít podobně jako standardní ukazatele. Automatizují některé manuální procesy, které způsobují běžné chyby.
Předpoklady: Ukazatel v C++ , Inteligentní ukazatele v C++.
Syntax
unique_ptr< A>ptr1 (nové A)>
Tady,
- unique_ptr : Určuje typ std::unique_ptr. V tomto případě jde o objekt typu A.
- nový A : Objekt typu A je dynamicky alokován na haldě pomocí operátoru new.
- ptr1 : Toto je název proměnné std::unique_ptr.
Co se stane, když se použije unique_ptr?
Když píšeme unique_ptr ptr1 (nové A), paměť je alokována na haldě pro instanci datového typu A. ptr1 je inicializován a ukazuje na nově vytvořený objekt A. Zde je ptr1 jediným vlastníkem nově vytvořeného objektu A a spravuje životnost tohoto objektu. To znamená, že když je ptr1 resetován nebo je mimo rozsah, paměť je automaticky uvolněna a objekt A je zničen.
Kdy použít unique_ptr?
Když je vyžadováno vlastnictví zdroje. Když chceme jediné nebo výhradní vlastnictví zdroje, měli bychom jít po jedinečných ukazatelích. Pouze jeden jedinečný ukazatel může ukazovat na jeden zdroj. Takže jeden jedinečný ukazatel nelze zkopírovat do jiného. Usnadňuje také automatické čištění, když dynamicky alokované objekty přejdou mimo rozsah, a pomáhá předcházet únikům paměti.
Poznámka: Musíme použít hlavičkový soubor pro použití těchto inteligentních ukazatelů.
Příklady Unique_ptr
Příklad 1:
Vytvořme strukturu A, která bude mít metodu nazvanou printA pro zobrazení nějakého textu. Pak v hlavní sekci vytvořte jedinečný ukazatel, který bude ukazovat na strukturu A. V tomto bodě tedy máme instanci struktury A a p1 na ni drží ukazatel.
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->tiskA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> >return> 0;> }> |
polymorfismus java
>
>Výstup
A struct.... 0x18dac20>
Příklad 2
Nyní vytvoříme další ukazatel p2 a pokusíme se zkopírovat ukazatel p1 pomocí operátoru přiřazení (=).
C++
seznam java array
// 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->tiskA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> > >// will give compile time error> >unique_ptr> p2 = p1;> >p2->tiskA();> >return> 0;> }> |
>
>
Výstup
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; | ^~~~~~~~~~>
Výše uvedený kód způsobí chybu při kompilaci, protože nemůžeme přiřadit ukazatel p2 k p1 v případě jedinečných ukazatelů. K tomuto účelu musíme použít sémantiku pohybu, jak je uvedeno níže.
python generuje uuid
Příklad 3
Správa objektu typu A pomocí sémantiky přesunu.
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->tiskA();> > >// 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->tiskA();> >cout << p1.get() << endl;> >cout << p2.get() << endl;> >return> 0;> }> |
>
>Výstup
A struct.... 0x2018c20 A struct.... 0 0x2018c20>
Všimněte si, že jakmile je adresa v ukazateli p1 zkopírována do ukazatele p2, adresa ukazatele p1 se změní na NULL(0) a adresa uložená v p2 je nyní stejná jako adresa uložená v p1, což ukazuje, že adresa v p1 byla přenesena do ukazatele. p2 pomocí sémantiky pohybu.