Condiție preliminară: Pointeri în C++
Pointerii sunt folosiți pentru accesarea resurselor care sunt externe programului - cum ar fi memoria heap. Deci, pentru accesarea memoriei heap (dacă se creează ceva în memoria heap), se folosesc pointerii. Când accesăm orice resursă externă, folosim doar o copie a resursei. Dacă îi facem modificări, îl schimbăm doar în versiunea copiată. Dar, dacă folosim un pointer către resursă, vom putea schimba resursa originală.
Probleme cu indicatoarele normale
Unele probleme cu pointerii normali în C++ sunt următoarele:
- Scurgeri de memorie: Acest lucru apare atunci când memoria este alocată în mod repetat de către un program, dar nu este niciodată eliberată. Acest lucru duce la un consum excesiv de memorie și în cele din urmă duce la o blocare a sistemului. Pointere suspendate: un pointer suspendat este un pointer care apare în momentul în care obiectul este de-alocat din memorie fără a modifica valoarea pointerului. Indicatori sălbatici: pointerii sălbatici sunt pointeri care sunt declarați și alocați memorie, dar pointerul nu este niciodată inițializat pentru a indica niciun obiect sau adresă validă. Incoerența datelor: Incoerența datelor apare atunci când unele date sunt stocate în memorie, dar nu sunt actualizate într-o manieră consecventă. Buffer Overflow: Când un pointer este folosit pentru a scrie date la o adresă de memorie care se află în afara blocului de memorie alocat. Acest lucru duce la coruperea datelor care pot fi exploatate de atacatori rău intenționați.
Exemplu:
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();> >}> }> |
>
>
Ieșire
Memory limit exceeded>
Explicaţie: În funcțiune distracţie , creează un pointer care indică spre Dreptunghi obiect. Obiectul Dreptunghi conține două numere întregi, lungime, și lăţime . Când funcţia distracţie se termină, p va fi distrus deoarece este o variabilă locală. Dar, memoria pe care a consumat-o nu va fi dealocată pentru că am uitat să o folosim șterge p; la sfarsitul functiei. Aceasta înseamnă că memoria nu va fi liberă pentru a fi folosită de alte resurse. Dar, nu mai avem nevoie de variabilă, avem nevoie de memorie.
În funcțiune, principal , distracţie este numită într-o buclă infinită. Asta înseamnă că va continua să creeze p . Va aloca din ce în ce mai multă memorie, dar nu le va elibera, deoarece nu am dealocat-o. Memoria irosită nu poate fi folosită din nou. Ceea ce este o scurgere de memorie. Intregul morman memoria poate deveni inutilă din acest motiv.
Indicatori inteligente
După cum știm în mod inconștient, nealocarea unui pointer provoacă o scurgere de memorie care poate duce la o blocare a programului. Limbaje Java, C# are Mecanisme de colectare a gunoiului pentru a dezaloca inteligent memoria neutilizată pentru a fi utilizată din nou. Programatorul nu trebuie să-și facă griji cu privire la scurgeri de memorie. C++ vine cu propriul său mecanism, adică Indicator inteligent . Când obiectul este distrus, eliberează și memoria. Deci, nu trebuie să-l ștergem, deoarece Smart Pointer se va ocupa de el.
A Indicator inteligent este o clasă wrapper peste un pointer cu un operator ca * și -> supraîncărcat. Obiectele clasei de indicatori inteligente arată ca indicatori normali. Dar, spre deosebire de Indicatori normale, poate dezaloca și elibera memoria obiectelor distruse.
Ideea este să luați o clasă cu un indicator, distrugător, și operatori supraîncărcați ca * și -> . Deoarece destructorul este apelat automat când un obiect iese din domeniul de aplicare, memoria alocată dinamic va fi ștearsă automat (sau numărul de referințe poate fi decrementat).
Exemplu:
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;> }> |
>
>Ieșire
20>
Diferența dintre pointere și pointere inteligente
| Indicator | Indicator inteligent |
|---|---|
| Un pointer este o variabilă care menține o adresă de memorie, precum și informații despre tipul de date despre acea locație de memorie. Un pointer este o variabilă care indică ceva din memorie. | Este un obiect alocat în stivă care înfășoară indicatori. Pointerii inteligenți, în termeni simpli, sunt clase care înglobează un pointer sau indicatori cu scop. |
| Nu este distrus sub nicio formă atunci când iese din domeniul său de aplicare | Se autodistruge atunci când iese din domeniul său de aplicare |
| Indicatoarele nu sunt atât de eficiente, deoarece nu acceptă nicio altă caracteristică. | Indicatoarele inteligente sunt mai eficiente deoarece au o caracteristică suplimentară de gestionare a memoriei. |
| Sunt foarte centrate pe muncă/manuale. | Sunt automate/preprogramate în natură. |
Notă: Acest lucru funcționează doar pentru int . Deci, va trebui să creăm un indicator inteligent pentru fiecare obiect? Nu , există o soluție, Șablon . În codul de mai jos, după cum puteți vedea T poate fi de orice tip.
înlocuiți o culoare în gimp
Exemplu:
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>>>> >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->() {>>> };> int> main()> {> >SmartPtr<>int>>ptr(>new> int>());> >*ptr = 20;> >cout << *ptr;> >return> 0;> }> |
>
>Ieșire
20>
Notă: Indicatoarele inteligente sunt utile și în gestionarea resurselor, cum ar fi mânerele de fișiere sau prizele de rețea.
Tipuri de indicatori inteligente
Bibliotecile C++ oferă implementări de pointeri inteligente în următoarele tipuri:
- auto_ptr
- unic_ptr
- shared_ptr
- slab_ptr
auto_ptr
Folosind auto_ptr, puteți gestiona obiectele obținute din noi expresii și le puteți șterge atunci când auto_ptr în sine este distrus. Când un obiect este descris prin auto_ptr, acesta stochează un pointer către un singur obiect alocat.
Notă: Acest șablon de clasă este depreciat începând cu C++11. unique_ptr este o facilitate nouă cu o funcționalitate similară, dar cu securitate îmbunătățită.
unic_ptr
unic_ptr stochează un singur indicator. Putem atribui un obiect diferit prin eliminarea obiectului curent din indicator.
Exemplu:
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; }> |
>
>Ieșire
50 50>
shared_ptr
Prin utilizarea shared_ptr mai mult de un pointer poate indica acest obiect la un moment dat și va menține a Contor de referință folosind use_count() metodă.

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; }> |
>
>Ieșire
50 50 50 2>
slab_ptr
Weak_ptr este un pointer inteligent care deține o referință neproprietă la un obiect. Este mult mai asemănător cu shared_ptr, cu excepția faptului că nu va menține a Contor de referință . În acest caz, un pointer nu va avea o fortăreață asupra obiectului. Motivul este dacă presupunem că pointerii țin obiectul și solicită alte obiecte, atunci aceștia pot forma a Impas.

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; }> |
>
>Ieșire
50 1>
Bibliotecile C++ oferă implementări de pointeri inteligente sub formă de auto_ptr, unique_ptr, shared_ptr și weak_ptr
tuplu python sortat