Älykkäät osoittimet C++:ssa
Edellytys: Osoittimet C++:ssa
Osoittimia käytetään ohjelman ulkopuolisiin resursseihin, kuten kasamuistiin, pääsyyn. Joten keon muistiin pääsyyn (jos keon muistiin luodaan jotain) käytetään osoittimia. Kun käytämme ulkoista resurssia, käytämme vain kopiota resurssista. Jos teemme siihen muutoksia, muutamme vain kopioitua versiota. Mutta jos käytämme osoitinta resurssiin, voimme muuttaa alkuperäistä resurssia.
Ongelmia tavallisten osoittimien kanssa
Jotkut ongelmat normaaleissa osoittimissa C++:ssa ovat seuraavat:
- Muistivuoto: Tämä tapahtuu, kun ohjelma varaa muistia toistuvasti, mutta sitä ei koskaan vapauteta. Tämä johtaa liialliseen muistinkulutukseen ja lopulta järjestelmän kaatumiseen. Roikkuvat osoittimet: Roikkuva osoitin on osoitin, joka esiintyy silloin, kun objektin varaus poistetaan muistista muuttamatta osoittimen arvoa. Villi osoittimet: Villi osoittimet ovat osoittimia, jotka on ilmoitettu ja varattu muistia, mutta osoitinta ei koskaan alusteta osoittamaan mihinkään kelvolliseen objektiin tai osoitteeseen. Tietojen epäjohdonmukaisuus: Tietojen epäjohdonmukaisuutta ilmenee, kun joitakin tietoja on tallennettu muistiin, mutta niitä ei päivitetä johdonmukaisesti. Puskurin ylivuoto: Kun osoitinta käytetään tietojen kirjoittamiseen muistiosoitteeseen, joka on varatun muistilohkon ulkopuolella. Tämä johtaa tietojen vioittumiseen, jota haitalliset hyökkääjät voivat hyödyntää.
Esimerkki:
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();> > }> }> |
Lähtö
Memory limit exceeded
Selitys: Toiminnassa hauskaa , se luo osoittimen, joka osoittaa Suorakulmio esine. Objekti Suorakulmio sisältää kaksi kokonaislukua, pituus, ja leveys . Kun toiminto hauskaa päättyy, p tuhotaan, koska se on paikallinen muuttuja. Mutta sen kuluttamaa muistia ei jaeta, koska unohdimme käyttää poista p; toiminnon lopussa. Tämä tarkoittaa, että muisti ei ole vapaa muiden resurssien käytettäväksi. Mutta emme enää tarvitse muuttujaa, tarvitsemme muistia.
Toiminnassa, pää , hauskaa kutsutaan äärettömässä silmukassa. Se tarkoittaa, että se jatkaa luomistaan s . Se varaa yhä enemmän muistia, mutta ei vapauta niitä, koska emme jakaneet sitä. Hukkaan mentyä muistia ei voi käyttää uudelleen. Mikä on muistivuoto. Koko pino muisti voi tulla hyödyttömäksi tästä syystä.
Älykkäät osoittimet
Kuten olemme tiedostaneet, osoittimen kohdistamatta jättäminen aiheuttaa muistivuodon, joka voi johtaa ohjelman kaatumiseen. Kielet Java, C# on Jätteiden keräysmekanismit käyttää älykkäästi käyttämätöntä muistia käytettäväksi uudelleen. Ohjelmoijan ei tarvitse huolehtia muistivuodoista. C++ keksii oman mekanisminsa Älykäs osoitin . Kun esine tuhoutuu, se vapauttaa myös muistin. Joten meidän ei tarvitse poistaa sitä, koska Smart Pointer käsittelee sen.
A Älykäs osoitin on kääreluokka osoittimen päällä operaattorin kaltaisella operaattorilla * ja -> ylikuormitettu. Älykäs osoitinluokan objektit näyttävät normaaleista osoittimista. Mutta toisin kuin Normaalit osoittimet, se voi purkaa ja vapauttaa tuhoutuneiden objektien muistin.
Ajatuksena on ottaa luokka osoittimella, hävittäjä, ja ylikuormitetut operaattorit kuten * ja -> . Koska tuhoaja kutsutaan automaattisesti, kun objekti menee soveltamisalan ulkopuolelle, dynaamisesti varattu muisti poistetaan automaattisesti (tai viitemäärää voidaan pienentää).
Esimerkki:
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;> }> |
Lähtö
20
Ero osoittimien ja älykkäiden osoittimien välillä
| Osoitin | Älykäs osoitin |
|---|---|
| Osoitin on muuttuja, joka säilyttää muistiosoitteen sekä tietotyyppitiedot kyseisestä muistipaikasta. Osoitin on muuttuja, joka osoittaa jotain muistissa. | Se on osoittimen käärittävä pino-allokoitu objekti. Älykkäät osoittimet ovat selkeästi sanottuna luokkia, jotka käärivät osoittimen, tai laajennettuja osoittimia. |
| Sitä ei tuhota missään muodossa, kun se menee soveltamisalansa ulkopuolelle | Se tuhoaa itsensä, kun se menee ulkopuolelle |
| Osoittimet eivät ole niin tehokkaita, koska ne eivät tue muita ominaisuuksia. | Älykkäät osoittimet ovat tehokkaampia, koska niissä on muistinhallinnan lisäominaisuus. |
| Ne ovat hyvin työvoimakeskeisiä/manuaalisia. | Ne ovat luonteeltaan automaattisia/esiohjelmoituja. |
Huomautus: Tämä toimii vain int . Joten meidän on luotava älykäs osoitin jokaiselle esineelle? Ei , on ratkaisu, Sapluuna . Alla olevassa koodissa kuten näet T voi olla mitä tahansa tyyppiä.
Esimerkki:
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>>> |