logo

Unique_ptr v C++

std::unique_ptr je pametni kazalec, predstavljen v C++11. Samodejno upravlja dinamično dodeljene vire na kupu. Pametni kazalci so le ovitki okoli običajnih starih kazalcev, ki vam pomagajo preprečiti razširjene napake. Namreč, pozabite izbrisati kazalec in povzročite uhajanje pomnilnika ali pomotoma dvakrat ali na napačen način izbrišete kazalec. Uporabljajo se lahko na podoben način kot standardni kazalci. Avtomatizirajo nekatere ročne postopke, ki povzročajo običajne napake.

Predpogoji: Kazalec v C++ , Pametni kazalci v C++.



Sintaksa

unique_ptr<  A>ptr1 (novo A )>

tukaj,

Kaj se zgodi, če uporabimo unique_ptr?

Ko napišemo unique_ptr ptr1 (novi A), je pomnilnik dodeljen na kopici za primerek podatkovnega tipa A. ptr1 je inicializiran in kaže na novo ustvarjen objekt A. Tu je ptr1 edini lastnik novo ustvarjenega objekta A in upravlja življenjsko dobo tega objekta. To pomeni, da ko je ptr1 ponastavljen ali izstopi iz obsega, se pomnilnik samodejno sprosti in A-jev objekt uniči.

Kdaj uporabiti unique_ptr?

Ko je zahtevano lastništvo vira. Kadar želimo eno ali izključno lastništvo vira, moramo poseči po edinstvenih kazalcih. Samo en edinstven kazalec lahko kaže na en vir. Torej enega edinstvenega kazalca ni mogoče kopirati v drugega. Omogoča tudi samodejno čiščenje, ko dinamično dodeljeni objekti izstopijo iz obsega, in pomaga preprečevati uhajanje pomnilnika.



Opomba: Uporabiti moramo datoteko glave za uporabo teh pametnih kazalcev.

Primeri Unique_ptr

Primer 1:

Ustvarimo strukturo A, ki bo imela metodo z imenom printA za prikaz besedila. Nato v glavnem razdelku ustvarimo edinstven kazalec, ki bo kazal na strukturo A. Na tej točki imamo torej primerek strukture A in p1 drži kazalec na to.

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->natisniA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> >return> 0;> }>

okrogla matematika java

>

kako dobiti trenutni datum v Javi
>

Izhod

A struct.... 0x18dac20>

Primer 2

Sedaj pa ustvarimo še en kazalec p2 in poskušali bomo kopirati kazalec p1 z uporabo operatorja dodelitve (=).

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->natisniA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> > >// will give compile time error> >unique_ptr> p2 = p1;> >p2->natisniA();> >return> 0;> }>

>

>

Izhod

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;  | ^~~~~~~~~~>

Zgornja koda bo povzročila napako pri času prevajanja, saj kazalca p2 ne moremo dodeliti p1 v primeru edinstvenih kazalcev. Za ta namen moramo uporabiti semantiko premika, kot je prikazano spodaj.

markdown s slikami

Primer 3

Upravljanje objekta tipa A z uporabo semantike premika.

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->natisniA();> > >// 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->natisniA();> >cout << p1.get() << endl;> >cout << p2.get() << endl;> >return> 0;> }>

>

>

Izhod

A struct.... 0x2018c20 A struct.... 0 0x2018c20>

Ko je naslov v kazalcu p1 prekopiran v kazalec p2, naslov kazalca p1 postane NULL(0) in naslov, ki ga shrani p2, je zdaj enak naslovu, ki ga shrani p1, kar kaže, da je bil naslov v p1 prenesen na kazalec p2 z uporabo semantike premika.