Předpoklad: Ukazatele v C++
Ukazatele se používají pro přístup ke zdrojům, které jsou externí vůči programu – jako je haldová paměť. Takže pro přístup k paměti haldy (pokud je něco vytvořeno v paměti haldy) se používají ukazatele. Při přístupu k jakémukoli externímu zdroji používáme pouze kopii zdroje. Pokud v něm provedeme nějaké změny, změníme ho pouze v zkopírované verzi. Pokud však použijeme ukazatel na zdroj, budeme moci změnit původní zdroj.
Problémy s normálními ukazateli
Některé problémy s normálními ukazateli v C++ jsou následující:
- Netěsnosti paměti: K tomu dochází, když je paměť opakovaně alokována programem, ale nikdy není uvolněna. To vede k nadměrné spotřebě paměti a nakonec vede ke zhroucení systému. Visící ukazatele: Visutý ukazatel je ukazatel, ke kterému dochází v době, kdy je objekt uvolněn z paměti, aniž by se změnila hodnota ukazatele. Divoké ukazatele: Divoké ukazatele jsou ukazatele, které jsou deklarovány a přiděleny paměti, ale ukazatel není nikdy inicializován, aby ukazoval na jakýkoli platný objekt nebo adresu. Nekonzistence dat: Nekonzistence dat nastává, když jsou některá data uložena v paměti, ale nejsou aktualizována konzistentním způsobem. Přetečení vyrovnávací paměti: Když se ukazatel používá k zápisu dat na adresu paměti, která je mimo alokovaný paměťový blok. To vede k poškození dat, která mohou zneužít zákeřní útočníci.
Pří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ýstup
Memory limit exceeded>
Vysvětlení: Ve funkci zábava , vytvoří ukazatel, který ukazuje na Obdélník objekt. Objekt Obdélník obsahuje dvě celá čísla, délka, a šířka . Když funkce zábava skončí, p bude zničen, protože jde o lokální proměnnou. Paměť, kterou spotřebovala, však nebude uvolněna, protože jsme ji zapomněli použít odstranit p; na konci funkce. To znamená, že paměť nebude volná pro použití jinými zdroji. Ale už nepotřebujeme proměnnou, potřebujeme paměť.
ve funkci, hlavní , zábava se volá v nekonečné smyčce. To znamená, že bude tvořit dál p . Bude alokovat stále více paměti, ale neuvolní je, protože jsme ji nepřidělili. Promarněnou paměť nelze znovu použít. Což je únik paměti. Celá halda paměť může být z tohoto důvodu nepoužitelná.
Inteligentní ukazatele
Jak jsme věděli, nevědomé neudělení ukazatele způsobí únik paměti, který může vést ke zhroucení programu. Jazyky Java, C# má Mechanismy sběru odpadků chytře uvolnit nevyužitou paměť k opětovnému použití. Programátor se nemusí obávat žádných úniků paměti. C++ přichází s vlastním mechanismem, který je Chytrý ukazatel . Když je objekt zničen, uvolní se také paměť. Nemusíme to tedy mazat, protože to zvládne Smart Pointer.
A Chytrý ukazatel je třída obalu nad ukazatelem s operátorem jako * a -> přetížené. Objekty třídy inteligentních ukazatelů vypadají jako normální ukazatele. Ale na rozdíl od Normální ukazatele, může uvolnit a uvolnit paměť zničených objektů.
Cílem je vzít třídu s ukazatelem, ničitel, a přetížení operátoři jako * a -> . Vzhledem k tomu, že destruktor je automaticky volán, když objekt překročí rozsah, dynamicky alokovaná paměť bude automaticky odstraněna (nebo může být snížen počet odkazů).
Pří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ýstup
20>
Rozdíl mezi ukazateli a inteligentními ukazateli
| Ukazatel | Chytrý ukazatel |
|---|---|
| Ukazatel je proměnná, která udržuje adresu paměti a také informace o datovém typu o tomto umístění v paměti. Ukazatel je proměnná, která ukazuje na něco v paměti. | Jedná se o objekt alokovaný do zásobníku. Inteligentní ukazatele, jednoduše řečeno, jsou třídy, které obalují ukazatel nebo ukazatele s rozsahem. |
| Není zničena v žádné formě, když se dostane mimo její rozsah | Zničí se, když se dostane mimo svůj rozsah |
| Ukazatele nejsou tak efektivní, protože nepodporují žádnou jinou funkci. | Inteligentní ukazatele jsou efektivnější, protože mají další funkci správy paměti. |
| Jsou velmi pracovně/manuální. | Jsou svou povahou automatické/předprogramované. |
Poznámka: Toto funguje pouze pro int . Takže budeme muset vytvořit Smart Ukazatel pro každý objekt? Ne , existuje řešení, Šablona . V kódu níže, jak vidíte T může být jakéhokoli typu.
modifikační klávesy
Pří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ýstup
20>
Poznámka: Inteligentní ukazatele jsou také užitečné při správě zdrojů, jako jsou popisovače souborů nebo síťové zásuvky.
Typy inteligentních ukazatelů
Knihovny C++ poskytují implementace inteligentních ukazatelů v následujících typech:
- auto_ptr
- unique_ptr
- shared_ptr
- slabý_ptr
auto_ptr
Pomocí auto_ptr můžete spravovat objekty získané z nových výrazů a mazat je, když je auto_ptr zničeno. Když je objekt popsán pomocí auto_ptr, ukládá ukazatel na jeden přidělený objekt.
Poznámka: Tato šablona třídy je od C++11 zastaralá. unique_ptr je nové zařízení s podobnou funkčností, ale s vylepšeným zabezpečením.
unique_ptr
unique_ptr ukládá pouze jeden ukazatel. Jiný objekt můžeme přiřadit odstraněním aktuálního objektu z ukazatele.
Pří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; }> |
>
zpětné volání peklo v javascriptu
>Výstup
50 50>
shared_ptr
Používáním shared_ptr více než jeden ukazatel může ukazovat na tento jeden objekt najednou a bude udržovat a Referenční počítadlo za použití use_count() metoda.

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; }> |
>
>Výstup
50 50 50 2>
slabý_ptr
Weak_ptr je inteligentní ukazatel, který obsahuje odkaz na objekt, který nevlastní. Je mnohem podobnější sdílenému_ptr kromě toho, že nebude udržovat a Referenční počítadlo . V tomto případě nebude mít ukazatel na objektu pevnost. Důvodem je, že pokud předpokládejme, že ukazatele drží objekt a požadují další objekty, mohou tvořit a Zablokování.

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ýstup
50 1>
Knihovny C++ poskytují implementace inteligentních ukazatelů ve formě auto_ptr, unique_ptr, shared_ptr a slabé_ptr