logo

Unique_ptr v C++

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,

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.