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.
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.

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.

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