Zaawansowane wykorzystanie wskaźników 147
32: }
33:
34: int main()35: {
36: ZwyklyKot *Frisky = new ZwyklyKot;
37: cout « "Frisky ma ” « Frisky->PobierzWiek() « " lat\n";
38: Frisky->UstawWiek(15);
39: cout « "Frisky ma " « Frisky->PobierzWiek() « " lat\n";
40: delete Frisky;
41: return 0;
42: }
Frisky ma 5 lat Frisky ma 15 lat
Klasa ZwyklyKot ma dwie zmienne wewnętrzne — wskaźniki na int
ANALIZA:
(patrz linie 18 i 19). Konstruktor (linie 22-26) inicjalizuje oba wskaźniki adresami zarezerwowanej pamięci na stercie i wpisuje pod te adresy wartości domyślne.
Destruktor (linie 28-32) zwalnia zarezerwowaną pamięć. Ponieważ jest to destruktor, to nie ma potrzeby przypisania wartości nuli wskaźnikom, ponieważ nie będą one już dłużej dostępne. W tym przypadku można pominąć zasadę przypisywania wartości nuli kasowanym wskaźnikom (aczkolwiek nic by się nie stało gdybyśmy i tutaj tę zasadę zastosowali).
Funkcja wywołująca, w tym przypadku main (), „nie wie”, że jegoWiek i jegoWaga są wskaźnikami. main() wywołuje metody PobierzWiek () i UstawWiek (),
a szczegóły operacji na pamięci zaszyte są wewnątrz implementacji klasy. W linii 40 kasowany jest obiekt Frisky, wywoływany jest automatycznie destruktor klasy. Destruktor kasuje wskaźniki. Jeśli wskaźniki wskazywały by na obiekty innej klasy, to zostałyby wywołane destruktory tych klas.
Każda wewnętrzna funkcja klasy ma ukryty parametr: wskaźnik this. this zawsze wskazuje na aktualny obiekt. Przy każdym wywołaniu metod PobierzWiek () albo UstawWiek (), wskaźnik this jest dołączany jako ukryty parametr Zadaniem wskaźnika this jest wskazywanie na obiekt, którego metoda została wywołana. Zazwyczaj nie będziesz go potrzebował; będziesz tylko wywoływać metody i zmieniać zmienne wewnętrzne. Jednak czasami będziesz musiał zagwarantować dostęp do obiektu (np. zwrócić adres aktualnego obiektu). W takiej sytuacji this będzie bardzo pomocne.
W normalnej sytuacji, aby dostać się do elementów klasy, nie potrzebujesz wskaźnika this. Możesz jednak bezpośrednio odwołać się do this. Ilustruje to listing
)
32
33
34
36
37
38
39
40
41
42
int roain () 35: {
ZwyklyKot *Frisky = new ZwyklyKot;
cout « "Frisky ma ” « Frisky->PobierzWiek() « " lat\n"; Frisky->UstawWiek(15);
cout « "Frisky ma " « Frisky->PobierzWiek() « " lat\n"; delete Frisky; return 0;
)
Frisky ma 5 lat Frisky ma 15 lat
ANALIZA
Klasa ZwyklyKot ma dwie zmienne wewnętrzne — wskaźniki na int (patrz linie 18 i 19). Konstruktor (linie 22-26) inicjalizuje oba wskaźniki adresami zarezerwowanej pamięci na stercie i wpisuje pod te adresy wartości domyślne.
Destruktor (linie 28-32) zwalnia zarezerwowaną pamięć. Ponieważ jest to destruktor, to nie ma potrzeby przypisania wartości nuli wskaźnikom, ponieważ nie będą one już dłużej dostępne. W tym przypadku można pominąć zasadę przypisywania wartości nuli kasowanym wskaźnikom (aczkolwiek nic by się nie stało gdybyśmy i tutaj tę zasadę zastosowali).
Funkcja wywołująca, w tym przypadku main (), „nie wie”, że jegoWiek i jegoWaga są wskaźnikami. main() wywołuje metody PobierzWiek() i UstawWiek(), a szczegóły operacji na pamięci zaszyte są wewnątrz implementacji klasy. W linii 40 kasowany jest obiekt Frisky, wywoływany jest automatycznie destruktor klasy. Destruktor kasuje wskaźniki. Jeśli wskaźniki wskazywały by na obiekty innej klasy, to zostałyby wywołane destruktory tych klas.
Każda wewnętrzna funkcja klasy ma ukryty parametr: wskaźnik this. this zawsze wskazuje na aktualny obiekt. Przy każdym wywołaniu metod PobierzWiek () albo OstawWiek (), wskaźnik this jest dołączany jako ukryty parametr Zadaniem wskaźnika this jest wskazywanie na obiekt, którego metoda została wywołana. Zazwyczaj nie będziesz go potrzebował; będziesz tylko wywoływać metody i zmieniać zmienne wewnętrzne. Jednak czasami będziesz musiał zagwarantować dostęp do obiektu (np. zwrócić adres aktualnego obiektu). W takiej sytuacji this będzie bardzo pomocne.
W normalnej sytuacji, aby dostać się do elementów klasy, nie potrzebujesz wskaźnika this. Możesz jednak bezpośrednio odwołać się do this. Ilustruje to listing 10.4.