Nödvändig förutsättning: Pekare i C++
Pekare används för att komma åt de resurser som är externa till programmet – som högminne. Så för att komma åt högminnet (om något skapas i högminnet) används pekare. När vi kommer åt någon extern resurs använder vi bara en kopia av resursen. Om vi gör några ändringar i den ändrar vi bara den i den kopierade versionen. Men om vi använder en pekare till resursen kommer vi att kunna ändra den ursprungliga resursen.
Problem med normala pekare
Några problem med normala pekare i C++ är följande:
- Minnesläckor: Detta inträffar när minnet tilldelas upprepade gånger av ett program men aldrig frigörs. Detta leder till överdriven minnesförbrukning och leder så småningom till en systemkrasch. Dingelpekare: En dinglande pekare är en pekare som inträffar vid den tidpunkt då objektet avallokeras från minnet utan att ändra pekarens värde. Wild Pointers: Wild Pointers är pekare som deklareras och tilldelas minne men pekaren initieras aldrig för att peka på något giltigt objekt eller adress. Datainkonsekvens: Datainkonsekvens uppstår när vissa data lagras i minnet men inte uppdateras på ett konsekvent sätt. Buffertspill: När en pekare används för att skriva data till en minnesadress som ligger utanför det tilldelade minnesblocket. Detta leder till korruption av data som kan utnyttjas av illvilliga angripare.
Exempel:
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>
Förklaring: I funktion roligt skapar den en pekare som pekar på Rektangel objekt. Objektet Rektangel innehåller två heltal, längd, och bredd . När funktionen roligt slutar, kommer p att förstöras eftersom det är en lokal variabel. Men minnet det förbrukade kommer inte att deallokeras eftersom vi har glömt att använda ta bort p; i slutet av funktionen. Det betyder att minnet inte kommer att vara fritt att användas av andra resurser. Men vi behöver inte variabeln längre, vi behöver minnet.
I funktion, huvud , roligt kallas i en oändlig slinga. Det betyder att det kommer att fortsätta skapa sid . Det kommer att tilldela mer och mer minne men kommer inte att frigöra dem eftersom vi inte deallokerade det. Minnet som slösas bort kan inte användas igen. Vilket är en minnesläcka. Hela högen minnet kan bli värdelöst av denna anledning.
Smarta pekare
Som vi har känt till omedvetet orsakar inte avallokering av en pekare en minnesläcka som kan leda till en krasch av programmet. Språk Java, C# har Mekanismer för insamling av sopor för att smart deallokera oanvänt minne för att användas igen. Programmeraren behöver inte oroa sig för några minnesläckor. C++ kommer med sin egen mekanism Smart pekare . När objektet förstörs frigör det också minnet. Så vi behöver inte ta bort det eftersom Smart Pointer hanterar det.
A Smart pekare är en omslagsklass över en pekare med en operatör som * och -> överbelastad. Objekten i klassen smarta pekare ser ut som vanliga pekare. Men till skillnad från Normala pekare, det kan deallokera och frigöra förstört objektminne.
Tanken är att ta en klass med en pekare, jagare, och överbelastade operatörer som * och -> . Eftersom destruktorn anropas automatiskt när ett objekt går utanför räckvidden, skulle det dynamiskt allokerade minnet automatiskt tas bort (eller referensantalet kan minskas).
Exempel:
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>
Skillnaden mellan pekare och smarta pekare
| Pekare | Smart pekare |
|---|---|
| En pekare är en variabel som upprätthåller en minnesadress såväl som information om datatyp om den minnesplatsen. En pekare är en variabel som pekar på något i minnet. | Det är ett pekaromslutande stack-allokerat objekt. Smarta pekare är i klartext klasser som omsluter en pekare, eller pekare med omfattning. |
| Den förstörs inte i någon form när den går utanför sitt räckvidd | Den förstör sig själv när den går utanför sitt räckvidd |
| Pekare är inte så effektiva eftersom de inte stöder någon annan funktion. | Smarta pekare är mer effektiva eftersom de har en extra funktion för minneshantering. |
| De är mycket arbetscentrerade/manuella. | De är automatiska/förprogrammerade till sin natur. |
Notera: Detta fungerar bara för int . Så vi måste skapa Smart Pointer för varje objekt? Nej , det finns en lösning, Mall . I koden nedan som du kan se T kan vara av vilken typ som helst.
strängbyggare
Exempel:
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>
Notera: Smarta pekare är också användbara vid hantering av resurser, som filhandtag eller nätverksuttag.
Typer av smarta pekare
C++-bibliotek tillhandahåller implementeringar av smarta pekare i följande typer:
- auto_ptr
- unik_ptr
- shared_ptr
- svag_ptr
auto_ptr
Med auto_ptr kan du hantera objekt som erhållits från nya uttryck och radera dem när själva auto_ptr förstörs. När ett objekt beskrivs genom auto_ptr lagras en pekare till ett enda allokerat objekt.
Notera: Denna klassmall är utfasad från och med C++11. unique_ptr är en ny anläggning med liknande funktionalitet, men med förbättrad säkerhet.
unik_ptr
unik_ptr lagrar endast en pekare. Vi kan tilldela ett annat objekt genom att ta bort det aktuella objektet från pekaren.
Exempel:
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; }> |
>
>
handledning för javascriptProduktion
50 50>
shared_ptr
Genom att använda shared_ptr mer än en pekare kan peka på det här objektet åt gången och det kommer att behålla en Referensräknare använda 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; }> |
>
>Produktion
50 50 50 2>
svag_ptr
Weak_ptr är en smart pekare som innehåller en icke-ägande referens till ett objekt. Det är mycket mer likt shared_ptr förutom att det inte kommer att upprätthålla a Referensräknare . I det här fallet kommer en pekare inte att ha ett fäste på objektet. Anledningen är att om antar att pekare håller objektet och begär andra objekt så kan de bilda en Dödläge.

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; }> |
>
>Produktion
50 1>
C++-bibliotek tillhandahåller implementeringar av smarta pekare i form av auto_ptr, unique_ptr, shared_ptr och weak_ptr