std::unique_ptr er en smart pointer introduceret i C++11. Den styrer automatisk de dynamisk allokerede ressourcer på heapen. Smarte pointere er blot indpakninger omkring almindelige gamle pointere, der hjælper dig med at forhindre udbredte fejl. Nemlig at glemme at slette en pointer og forårsage en hukommelseslækage eller ved et uheld at slette en pointer to gange eller på den forkerte måde. De kan bruges på samme måde som standardpointere. De automatiserer nogle af de manuelle processer, der forårsager almindelige fejl.
Forudsætninger: Pointer i C++ , Smarte pointere i C++.
Syntaks
unique_ptr< A>ptr1 (nyt A )>
Her,
- unik_ptr : Den specificerer typen af std::unique_ptr. I dette tilfælde - et objekt af type A.
- ny A : Et objekt af type A allokeres dynamisk på heapen ved hjælp af den nye operator.
- ptr1 : Dette er navnet på variablen std::unique_ptr.
Hvad sker der, når unique_ptr bruges?
Når vi skriver unik_ptr ptr1 (nyt A), hukommelse er allokeret på heapen for en forekomst af datatype A. ptr1 initialiseres og peger på nyoprettet A-objekt. Her er ptr1 den eneste ejer af det nyoprettede objekt A, og det styrer dette objekts levetid. Dette betyder, at når ptr1 nulstilles eller går uden for scope, bliver hukommelsen automatisk deallokeret, og A's objekt bliver ødelagt.
Hvornår skal man bruge unique_ptr?
Når ejerskab af ressource er påkrævet. Når vi ønsker enkelt eller eksklusivt ejerskab af en ressource, så bør vi gå efter unikke pointer. Kun én unik pointer kan pege på én ressource. Så én unik pointer kan ikke kopieres til en anden. Det letter også automatisk oprydning, når dynamisk allokerede objekter går uden for rækkevidde, og hjælper med at forhindre hukommelseslækager.
Bemærk: Vi skal bruge header-fil til brug af disse smarte pointere.
Eksempler på Unique_ptr
Eksempel 1:
Lad os skabe en struktur A, og den vil have en metode kaldet printA til at vise noget tekst. Så lad os i hovedafsnittet skabe en unik markør, der peger på strukturen A. Så på dette tidspunkt har vi en forekomst af struktur A, og p1 holder markøren til den.
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;> }> |
streng.format
>
>Produktion
A struct.... 0x18dac20>
Eksempel 2
Lad os nu oprette en anden pointer p2, og vi vil prøve at kopiere pointeren p1 ved hjælp af tildelingsoperatoren (=).
C++
kali linux kommandoer
// 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;> }> |
>
>
Produktion
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; | ^~~~~~~~~~>
Ovenstående kode vil give kompileringstidsfejl, da vi ikke kan tildele pointer p2 til p1 i tilfælde af unikke pointere. Vi er nødt til at bruge bevægelsessemantikken til sådanne formål som vist nedenfor.
img css align
Eksempel 3
Håndtering af objekt af type A ved hjælp af bevægelsessemantik.
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;> }> |
>
>Produktion
A struct.... 0x2018c20 A struct.... 0 0x2018c20>
Bemærk når adressen i pointer p1 er kopieret til pointer p2, pointer p1's adresse bliver NULL(0), og adressen gemt af p2 er nu den samme som adressen gemt af p1, hvilket viser at adressen i p1 er blevet overført til pointeren p2 ved hjælp af move-semantikken.