Poznaj C++ w$ godziny0188

Poznaj C++ w$ godziny0188



177


Zaawansowane referencje i wskaźniki

18:    ZwyklyKot::ZwyklyKot(int wiek, int waga):

19:    jegoWiek(wiek), jegoWaga(waga) (}

20:

21:    ZwyklyKot & FunkcjaO;

22:

23:    int main()

24:    {

25:    ZwyklyKot & rKot = FunkcjaO;

26:    int wiek = rKot.PobierzWiek();

27:    cout    « "rKot ma " « wiek    «    "    lat\n";

28:    cout    « "SrKot: " « SrKot    «    endl;

29:    // Co zrobisz z tą    pamięcią?

30:    ZwyklyKot * pKot    =    SrKot;

31:    delete pKot;

32:    //O    jej! rKot wskazuje na    ??

33:    return 0;

34:    }

35:

36:    ZwyklyKot SFunkcjaO

37:    {

38:    ZwyklyKot * pFrisky = new ZwyklyKot(5,9);

39:    cout « "pFrisky: " « pFrisky « endl;

40:    return *pFrisky;

41:    )

EFEKT DZIAŁANIA:

pFrisky: 0x2bf4 rKot ma 5 lat SrKot: 0x2bf4


Ten program się kompiluje i pozornie działa. Jednak jest to klasyczna, programistyczna bomba zegarowa z opóźnionym zapłonem!


Funkcja Funkcja () została zmieniona tak, że nie zwraca już referencji

ANALIZA:


do lokalnego obiektu. Teraz pamięć jest rezerwowana na stercie i przypisywana do wskaźnika w linii 38. Adres przechowywany przez wskaźnik jest wypisywany, a następnie są zwracane referencje do obiektu przez niego wskazywanego.

W linii 25, wartość zwracana z funkcji jest przypisywana do referencji obiektu klasy ZwyklyKot. Obiekt ten wykorzystujemy do odczytania wieku kota (linia 26 i 27).

Dowodem na to, że referencja zadeklarowana w main () odnosi się do obiektu stworzonego na stercie jest odczytanie adresu tej referencji. Jest on taki sam jak adres wypisany w funkcji Funkcja ().

Dobrze. Ale jak teraz zwolnić zarezerwowaną pamięć? Nie można skasować referencji za pomocą delete. Jedyne nasuwające się rozwiązanie polega na zadeklarowaniu kolejnego wskaźnika i zainicjowaniu go adresem odczytanym z rKot. W ten sposób możemy zwolnić zarezerwowaną pamięć. Jednak i tu pojawia się kolejny

Zaawansowane referencje i wskaźniki

177


18:    ZwyklyKot::ZwyklyKot(int wiek, int waga):

19:    jegoWiek(wiek), jegoWaga(waga) ()

20:

21:    ZwyklyKot & Funkcja ();

22:

23:    int main()

24:    (

25:    ZwyklyKot & rKot = Funkcja();

26:    int wiek = rKot.PobierzWiek();

27:    cout    « "rKot ma " « wiek    «    "    lat\n";

28:    cout    « "SrKot: " « SrKot    «    endl;

29:    // Co zrobisz z tą    pamięcią?

30:    ZwyklyKot * pKot    =    SrKot;

31:    delete pKot;

32:    // O    jej! rKot wskazuje na    ??

33:    return 0;

34:    >

35:

36:    ZwyklyKot SFunkcjaf)

37:    (

38:    ZwyklyKot * pFrisky = new ZwyklyKot(5,9);

39:    cout « "pFrisky: " « pFrisky « endl;

40:    return ‘pFrisky;

41:    )

EFEKT DZIAŁANIA:

pFrisky: 0x2bf4 rKot ma 5 lat SrKot: 0x2bf4


Ten program się kompiluje i pozornie działa. Jednak jest to klasyczna, programistyczna bomba zegarowa z opóźnionym zapłonem!


Funkcja Funkcja () została zmieniona tak, że nie zwraca już referencji do lokalnego obiektu. Teraz pamięć jest rezerwowana na stercie i przypisywana do wskaźnika w linii 38. Adres przechowywany przez wskaźnik jest wypisywany, a następnie są zwracane referencje do obiektu przez niego wskazywanego.

W linii 25, wartość zwracana z funkcji jest przypisywana do referencji obiektu klasy ZwyklyKot. Obiekt ten wykorzystujemy do odczytania wieku kota (linia 26 i 27).

Dowodem na to, że referencja zadeklarowana w main () odnosi się do obiektu stworzonego na stercie jest odczytanie adresu tej referencji. Jest on taki sam jak adres wypisany w funkcji Funkcja ().

Dobrze. Ale jak teraz zwolnić zarezerwowaną pamięć? Nie można skasować referencji za pomocą delete. Jedyne nasuwające się rozwiązanie polega na zadeklarowaniu kolejnego wskaźnika i zainicjowaniu go adresem odczytanymi z rKot. W ten sposób możemy zwolnić zarezerwowaną pamięć. Jednak i tu pojawia się kolejny


Wyszukiwarka

Podobne podstrony:
Poznaj C++ w$ godziny0180 169Zaawansowane referencje i wskaźniki 39:    FunkcjaDruga(
Poznaj C++ w$ godziny0182 Zaawansowane referencje i wskaźniki 171 int PobierzWiek() const { return j
Poznaj C++ w$ godziny0184 Zaawansowane referencje i wskaźniki 173 Ponieważ wiemy, że obiekt nie będz
Poznaj C++ w$ godziny0186 175Zaawansowane referencje i wskaźniki Wskaźnik plnt jest deklarowany i in
Poznaj C++ w$ godziny0190 Zaawansowane referencje i wskaźniki 179 ZAWSZE NIGDY Zawsze przekazuj p
Poznaj C++ w$ godziny0156 145Zaawansowane wykorzystanie wskaźników W liniach 6-13 deklarujemy klasę
Poznaj C++ w$ godziny0178 Godzina 12Zaawansowane referencje i wskaźniki W ciągu ostatnich trzech god
Poznaj C++ w$ godziny0158 Zaawansowane wykorzystanie wskaźników 147 32:    } 33: 34:
Poznaj C++ w$ godziny0160 Zaawansowane wykorzystanie wskaźników 149Do czego służy wskaźnik this Gdyb
Poznaj C++ w$ godziny0162 Zaawansowane wykorzystanie wskaźników 151 Zaawansowane wykorzystanie wskaź
Poznaj C++ w$ godziny0140 Wskaźniki 129 Wskaźniki 129 13 14 15 16 17 18 cout « "longVar: "
Poznaj C++ w$ godziny0165 154 Godzina 11 Wskaźniki są zmiennymi przechowującymi adresy innych obiekt
Poznaj C++ w$ godziny0172 Referencje 161 Referencje 161 18 { 19 int temp; 20 21 cout «
Poznaj C++ w$ godziny0010 Spis treści    ix 11    Referencje
Poznaj C++ w$ godziny0034 18 Godzina 2Listing 2.2. hello . CPP, demonstracja komentarzy 1:  &nb
Poznaj C++ w$ godziny0078 64 Godzina 5 17:    float Konwertuj(float Fer) 18: { 19: &n
Poznaj C++ w$ godziny0084 70 Godzina 5 70 Godzina 5 8: 9: 10 11 12 13 14 15 16 17 18 19 20
Poznaj C++ w$ godziny0089 Funkcje 75 Kiedy wartość jest odkładana na stos, to jest umieszczana w kom

więcej podobnych podstron