Forudsætning: Pointere i C++
Pointere bruges til at få adgang til de ressourcer, der er eksterne i forhold til programmet - som heap-hukommelse. Så for at få adgang til heap-hukommelsen (hvis der er oprettet noget i heap-hukommelsen), bruges pointere. Når vi tilgår enhver ekstern ressource, bruger vi blot en kopi af ressourcen. Hvis vi laver ændringer i det, ændrer vi det bare i den kopierede version. Men hvis vi bruger en pegepind til ressourcen, vil vi være i stand til at ændre den oprindelige ressource.
Problemer med normale pointere
Nogle problemer med normale pointere i C++ er som følger:
- Hukommelseslækager: Dette sker, når hukommelsen gentagne gange tildeles af et program, men aldrig frigives. Dette fører til for stort hukommelsesforbrug og fører til sidst til et systemnedbrud. Dinglende pointer: En dinglende pointer er en pointer, der opstår på det tidspunkt, hvor objektet fjernes fra hukommelsen uden at ændre værdien af pointeren. Wild pointers: Wild pointers er pointere, der er erklæret og tildelt hukommelse, men pointeren initialiseres aldrig til at pege på et gyldigt objekt eller adresse. Datainkonsistens: Datainkonsistens opstår, når nogle data er gemt i hukommelsen, men ikke opdateres på en ensartet måde. Bufferoverløb: Når en pointer bruges til at skrive data til en hukommelsesadresse, der er uden for den tildelte hukommelsesblok. Dette fører til korruption af data, som kan udnyttes af ondsindede angribere.
Eksempel:
C++
// C++ program to demonstrate working of a Pointers> #include> using> namespace> std;> class> Rectangle {> private>:> >int> length;> >int> breadth;> };> void> fun()> {> >// By taking a pointer p and> >// dynamically creating object> >// of class rectangle> >Rectangle* p =>new> Rectangle();> }> int> main()> {> >// Infinite Loop> >while> (1) {> >fun();> >}> }> |
>
>
Produktion
Memory limit exceeded>
Forklaring: I funktion sjovt , skaber det en pointer, der peger på Rektangel objekt. Objektet Rektangel indeholder to heltal, længde, og bredde . Når funktionen sjovt slutter, vil p blive ødelagt, da det er en lokal variabel. Men den hukommelse, den forbrugte, vil ikke blive deallokeret, fordi vi har glemt at bruge slette p; i slutningen af funktionen. Det betyder, at hukommelsen ikke er fri til at blive brugt af andre ressourcer. Men vi har ikke brug for variablen længere, vi har brug for hukommelsen.
I funktion, vigtigste , sjovt kaldes i en uendelig løkke. Det betyder, at det bliver ved med at skabe s . Det vil tildele mere og mere hukommelse, men vil ikke frigøre dem, da vi ikke tildelte det. Den hukommelse, der er spildt, kan ikke bruges igen. Hvilket er en hukommelseslækage. Hele dynge hukommelse kan blive ubrugelig af denne grund.
Smarte pointere
Som vi har vidst ubevidst, forårsager ikke deallokering af en pointer en hukommelseslækage, der kan føre til et nedbrud af programmet. Sprog Java, C# har Affaldsopsamlingsmekanismer for smart at tildele ubrugt hukommelse til at blive brugt igen. Programmøren behøver ikke at bekymre sig om hukommelseslækager. C++ kommer med sin egen mekanisme, dvs Smart Pointer . Når objektet er ødelagt, frigør det også hukommelsen. Så vi behøver ikke at slette det, da Smart Pointer vil håndtere det.
EN Smart Pointer er en wrapper-klasse over en pointer med en operator som * og -> overbelastet. Objekterne i smart pointer-klassen ligner normale pointere. Men i modsætning til Normale pointer, det kan deallokere og frigøre ødelagt objekthukommelse.
Ideen er at tage en klasse med en pointer, destroyer, og overbelastede operatører som * og -> . Da destruktoren automatisk kaldes, når et objekt går uden for scope, vil den dynamisk allokerede hukommelse automatisk blive slettet (eller referenceantallet kan nedsættes).
Eksempel:
C++
// C++ program to demonstrate the working of Smart Pointer> #include> using> namespace> std;> class> SmartPtr {> >int>* ptr;>// Actual pointer> public>:> >// Constructor: Refer> >// techcodeview.com for use of> >// explicit keyword> >explicit> SmartPtr(>int>* p = NULL) { ptr = p; }> >// Destructor> >~SmartPtr() {>delete> (ptr); }> >// Overloading dereferencing operator> >int>& operator*() {>return> *ptr; }> };> int> main()> {> >SmartPtr ptr(>new> int>());> >*ptr = 20;> >cout << *ptr;> >// We don't need to call delete ptr: when the object> >// ptr goes out of scope, the destructor for it is> >// automatically called and destructor does delete ptr.> >return> 0;> }> |
>
>Produktion
20>
Forskellen mellem pointere og smarte pointere
| Pointer | Smart Pointer |
|---|---|
| En pointer er en variabel, der vedligeholder en hukommelsesadresse samt datatypeoplysninger om denne hukommelsesplacering. En pointer er en variabel, der peger på noget i hukommelsen. | Det er et pointer-indpakning stak-allokeret objekt. Smart pointers er kort sagt klasser, der omslutter en pointer, eller scoped pointers. |
| Det ødelægges ikke i nogen form, når det går uden for sit anvendelsesområde | Den ødelægger sig selv, når den går uden for sit omfang |
| Pointere er ikke så effektive, da de ikke understøtter nogen anden funktion. | Smarte pointere er mere effektive, da de har en ekstra funktion til hukommelsesstyring. |
| De er meget arbejdscentrerede/manuelle. | De er automatiske/forprogrammerede. |
Bemærk: Dette virker kun for int . Så vi bliver nødt til at oprette Smart Pointer for hvert objekt? Ingen , der er en løsning, Skabelon . I koden nedenfor som du kan se T kan være af enhver art.
nfa eksempler
Eksempel:
C++
// C++ program to demonstrate the working of Template and> // overcome the issues which we are having with pointers> #include> using> namespace> std;> // A generic smart pointer class> template> <>class> T>>class> SmartPtr {> >T* ptr;>// Actual pointer> public>:> >// Constructor> >explicit> SmartPtr(T* p = NULL) { ptr = p; }> >// Destructor> >~SmartPtr() {>delete> (ptr); }> >// Overloading dereferencing operator> >T& operator*() {>return> *ptr; }> >// Overloading arrow operator so that> >// members of T can be accessed> >// like a pointer (useful if T represents> >// a class or struct or union type)> >T* operator->() {>return> ptr; }> };> int> main()> {> >SmartPtr<>int>>ptr(>new> int>());> >*ptr = 20;> >cout << *ptr;> >return> 0;> }> |
>
>Produktion
20>
Bemærk: Smarte pointere er også nyttige til styring af ressourcer, såsom filhåndtag eller netværkssockets.
Typer af smarte pointere
C++ biblioteker leverer implementeringer af smarte pointere i følgende typer:
- auto_ptr
- unik_ptr
- delt_ptr
- svag_ptr
auto_ptr
Ved at bruge auto_ptr kan du administrere objekter, der er opnået fra nye udtryk, og slette dem, når selve auto_ptr bliver ødelagt. Når et objekt beskrives gennem auto_ptr, gemmer det en pointer til et enkelt allokeret objekt.
Bemærk: Denne klasseskabelon er forældet fra og med C++11. unique_ptr er en ny facilitet med en lignende funktionalitet, men med forbedret sikkerhed.
unik_ptr
unik_ptr gemmer kun én pointer. Vi kan tildele et andet objekt ved at fjerne det aktuelle objekt fra markøren.
Eksempel:
C++
// C++ program to demonstrate the working of unique_ptr> // Here we are showing the unique_pointer is pointing to P1.> // But, then we remove P1 and assign P2 so the pointer now> // points to P2.> #include> using> namespace> std;> // Dynamic Memory management library> #include> class> Rectangle {> >int> length;> >int> breadth;> public>:> >Rectangle(>int> l,>int> b)> >{> >length = l;> >breadth = b;> >}> >int> area() {>return> length * breadth; }> };> int> main()> {> // --/ Smart Pointer> >unique_ptr P1(>new> Rectangle(10, 5));> >cout // This'll print 50 // unique_ptr P2(P1); unique_ptr P2; P2 = move(P1); // This'll print 50 cout // cout return 0; }> |
>
>Produktion
50 50>
delt_ptr
Ved hjælp af delt_ptr mere end én pointer kan pege på dette ene objekt ad gangen, og det vil bevare en Referencetæller bruger use_count() metode.

C++
// C++ program to demonstrate the working of shared_ptr> // Here both smart pointer P1 and P2 are pointing to the> // object Addition to which they both maintain a reference> // of the object> #include> using> namespace> std;> // Dynamic Memory management library> #include> class> Rectangle {> >int> length;> >int> breadth;> public>:> >Rectangle(>int> l,>int> b)> >{> >length = l;> >breadth = b;> >}> >int> area() {>return> length * breadth; }> };> int> main()> {> >//---/ Smart Pointer> >shared_ptr P1(>new> Rectangle(10, 5));> >// This'll print 50> >cout shared_ptr P2; P2 = P1; // This'll print 50 cout // This'll now not give an error, cout // This'll also print 50 now // This'll print 2 as Reference Counter is 2 cout << P1.use_count() << endl; return 0; }> |
>
>Produktion
50 50 50 2>
svag_ptr
Weak_ptr er en smart pointer, der indeholder en ikke-ejer reference til et objekt. Det ligner meget mere shared_ptr, bortset fra at det ikke opretholder en Referencetæller . I dette tilfælde vil en pointer ikke have en højborg på objektet. Årsagen er, hvis antag, at pointere holder objektet og anmoder om andre objekter, så kan de danne en dødvande.

C++
// C++ program to demonstrate the working of weak_ptr> // Here both smart pointer P1 and P2 are pointing to the> // object Addition to which they both does not maintain> // a reference of the object> #include> using> namespace> std;> // Dynamic Memory management library> #include> class> Rectangle {> >int> length;> >int> breadth;> public>:> >Rectangle(>int> l,>int> b)> >{> >length = l;> >breadth = b;> >}> >int> area() {>return> length * breadth; }> };> int> main()> {> >//---/ Smart Pointer> >shared_ptr P1(>new> Rectangle(10, 5));> > >// create weak ptr> >weak_ptr P2 (P1);> > >// This'll print 50> >cout // This'll print 1 as Reference Counter is 1 cout << P1.use_count() << endl; return 0; }> |
kortlægning i maskinskrift
>
>Produktion
50 1>
C++ biblioteker leverer implementeringer af smarte pointere i form af auto_ptr, unique_ptr, shared_ptr og weak_ptr