logo

Inteligentné ukazovatele v C++

Predpoklad: Ukazovatele v C++

Ukazovatele sa používajú na prístup k zdrojom, ktoré sú pre program externé – ako je halda pamäte. Takže na prístup k pamäti haldy (ak sa niečo vytvorí v pamäti haldy) sa používajú ukazovatele. Pri prístupe k akémukoľvek externému zdroju používame iba kópiu zdroja. Ak v ňom urobíme nejaké zmeny, zmeníme ho iba v skopírovanej verzii. Ak však použijeme ukazovateľ na zdroj, budeme môcť zmeniť pôvodný zdroj.



Problémy s normálnymi ukazovateľmi

Niektoré problémy s normálnymi ukazovateľmi v C++ sú nasledovné:

    Úniky pamäte: K tomu dochádza, keď je pamäť opakovane prideľovaná programom, ale nikdy sa neuvoľňuje. To vedie k nadmernej spotrebe pamäte a nakoniec vedie k zlyhaniu systému. Visiace ukazovatele: Visiaci ukazovateľ je ukazovateľ, ktorý sa vyskytuje v čase, keď je objekt zrušený z pamäte bez zmeny hodnoty ukazovateľa. Divoké ukazovatele: Divoké ukazovatele sú ukazovatele, ktoré sú deklarované a pridelená pamäť, ale ukazovateľ nie je nikdy inicializovaný, aby ukazoval na akýkoľvek platný objekt alebo adresu. Nekonzistencia údajov: Nekonzistencia údajov nastáva, keď sú niektoré údaje uložené v pamäti, ale nie sú aktualizované konzistentným spôsobom. Pretečenie vyrovnávacej pamäte: Keď sa ukazovateľ používa na zapisovanie údajov na adresu pamäte, ktorá je mimo prideleného pamäťového bloku. To vedie k poškodeniu údajov, ktoré môžu zneužiť zákerní útočníci.

Príklad:

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();> >}> }>

>

>

Výkon

Memory limit exceeded>

Vysvetlenie: Vo funkcii zábava , vytvorí ukazovateľ, ktorý ukazuje na Obdĺžnik objekt. Objekt Obdĺžnik obsahuje dve celé čísla, dĺžka, a šírka . Keď funkcia zábava skončí, p sa zničí, keďže ide o lokálnu premennú. Pamäť, ktorú spotrebovala, však nebude uvoľnená, pretože sme ju zabudli použiť vymazať p; na konci funkcie. To znamená, že pamäť nebude môcť byť voľne použitá inými zdrojmi. Ale už nepotrebujeme premennú, potrebujeme pamäť.

Vo funkcii, Hlavná , zábava sa volá v nekonečnej slučke. To znamená, že bude pokračovať vo vytváraní p . Pridelí stále viac pamäte, ale neuvoľní ich, keďže sme ju nepridelili. Premrhaná pamäť sa nedá znova použiť. Čo je únik pamäte. Celá hromada pamäť môže byť z tohto dôvodu zbytočná.

Inteligentné ukazovatele

Ako vieme, nevedomé uvoľnenie ukazovateľa spôsobuje únik pamäte, ktorý môže viesť k zlyhaniu programu. Jazyky Java, C# má Mechanizmy zberu odpadu na inteligentné uvoľnenie nevyužitej pamäte na opätovné použitie. Programátor sa nemusí obávať žiadneho úniku pamäte. C++ prichádza s vlastným mechanizmom, ktorý je Inteligentný ukazovateľ . Keď je objekt zničený, uvoľní sa aj pamäť. Nemusíme ho teda odstraňovať, pretože to zvládne Smart Pointer.

A Inteligentný ukazovateľ je trieda obalu nad ukazovateľom s operátorom ako * a -> preťažený. Objekty triedy inteligentných ukazovateľov vyzerajú ako normálne ukazovatele. Ale na rozdiel od Normálne ukazovatele, môže uvoľniť a uvoľniť pamäť zničeného objektu.

Myšlienkou je absolvovať triedu s ukazovateľom, ničiteľ, a preťažení operátori ako * a -> . Keďže deštruktor sa automaticky volá, keď objekt prekročí rozsah, dynamicky alokovaná pamäť sa automaticky vymaže (alebo sa môže znížiť počet odkazov).

Príklad:

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;> }>

>

>

Výkon

20>

Rozdiel medzi ukazovateľmi a inteligentnými ukazovateľmi

Ukazovateľ

Inteligentný ukazovateľ

Ukazovateľ je premenná, ktorá uchováva adresu pamäte, ako aj informácie o type údajov o tomto mieste v pamäti. Ukazovateľ je premenná, ktorá ukazuje na niečo v pamäti. Je to objekt alokovaný zásobníkom na obalenie ukazovateľa. Inteligentné ukazovatele, v jednoduchosti, sú triedy, ktoré obalujú ukazovateľ alebo ukazovatele s rozsahom.
Nie je zničená v žiadnej forme, keď sa dostane mimo jej rozsah Zničí sa, keď sa dostane mimo svoj rozsah
Ukazovatele nie sú také efektívne, pretože nepodporujú žiadnu inú funkciu. Inteligentné ukazovatele sú efektívnejšie, pretože majú ďalšiu funkciu správy pamäte.
Sú veľmi zamerané na prácu/manuálne. Sú svojou povahou automatické/predprogramované.

Poznámka: Toto funguje len pre int . Takže budeme musieť vytvoriť inteligentný ukazovateľ pre každý objekt? Nie , existuje riešenie, Šablóna . V kóde nižšie, ako vidíte T môže byť akéhokoľvek typu.

zoznam uzlov v jazyku Java

Príklad:

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;> }>

>

>

Výkon

20>

Poznámka: Inteligentné ukazovatele sú tiež užitočné pri správe zdrojov, ako sú napríklad popisovače súborov alebo sieťové zásuvky.

Typy inteligentných ukazovateľov

Knižnice C++ poskytujú implementácie inteligentných ukazovateľov v nasledujúcich typoch:

  • auto_ptr
  • unique_ptr
  • shared_ptr
  • slabý_ptr

auto_ptr

Pomocou auto_ptr môžete spravovať objekty získané z nových výrazov a vymazať ich, keď je samotný auto_ptr zničený. Keď je objekt opísaný prostredníctvom auto_ptr, ukladá ukazovateľ na jeden alokovaný objekt.

Poznámka: Táto šablóna triedy je od C++ 11 zastaraná. unique_ptr je nové zariadenie s podobnou funkcionalitou, ale s vylepšeným zabezpečením.

unique_ptr

unique_ptr ukladá iba jeden ukazovateľ. Odstránením aktuálneho objektu z ukazovateľa môžeme priradiť iný objekt.

Jedinečné ukazovatele v C++

Príklad:

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; }>

>

>

Výkon

50 50>

shared_ptr

Používaním shared_ptr viac ako jeden ukazovateľ môže ukazovať na tento jeden objekt naraz a bude udržiavať a Referenčné počítadlo pomocou use_count() metóda.

Zdieľaný ukazovateľ v C++

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; }>

>

vlc sťahujte videá z youtube
>

Výkon

50 50 50 2>

slabý_ptr

Weak_ptr je inteligentný ukazovateľ, ktorý obsahuje odkaz na objekt, ktorý nevlastní. Oveľa viac sa podobá shared_ptr okrem toho, že nezachová a Referenčné počítadlo . V tomto prípade ukazovateľ nebude mať na objekte pevnosť. Dôvodom je, že ak predpokladajme, že ukazovatele držia objekt a žiadajú o ďalšie objekty, môžu tvoriť a Zablokovanie.

Slabý ukazovateľ v C++

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; }>

>

>

Výkon

50 1>

Knižnice C++ poskytujú implementáciu inteligentných ukazovateľov vo forme auto_ptr, unique_ptr, shared_ptr a Slabý_ptr