Tablice 223
Rodzina jest wskaźnikiem do tablicy na stercie. Kiedy w linii 33 odwołujemy się do wskaźnika pKot, to wstawiamy do tablicy obiekt klasy KOT (dlaczego nie? tablica znajduje się przecież na stercie). Ale pKot jest w następnej iteracji wykorzystywany do stworzenia kolejnego obiektu. Czy nie pojawia się tutaj niebezpieczeństwo utraty wskaźników do obiektów w tablicy?
Byłby to wielki problem, gdyby nie fakt, że skasowanie wskaźnika Rodzina (za pomocą delete) zwolni całą pamięć zarezerwowaną dla tablicy. Kompilator potrafi usunąć każdy obiekt z tablicy i zwolnić zajmowaną pamięć.
Żeby się o tym przekonać, zmień w liniach 26, 29 i 36 rozmiar tablicy z 500 na 10 i usuń komentarz z linii 21. Uruchom program, a przekonasz się, że w momencie jego zakończenia zostanie wywołany destruktor każdego ze stworzonych obiektów.
Jeśli tworzysz obiekt za pomocą new to zawsze musisz go usunąć za pomocą delete. Podobnie, gdy tworzysz tablicę z wykorzystaniem new <klasa> [rozmiar] , to kasujesz ją potem za pomocą delete [ ]. Nawiasy są informacją dla
kompilatora, że skasowaniu ma ulec cała tablica.
Jeśli pominąłbyś nawiasy, to usunięty zostałby tylko pierwszy element tablicy. Możesz to sprawdzić. Usuń nawiasy w linii 39 i komentarz w linii 21. Po uruchomieniu programu zobaczysz, że destruktor zostanie wywołany tylko jeden raz. Gratulacje! Właśnie ubyło Ci pamięci!
ZAWSZE |
NIGDY |
Zawsze pamiętaj, że n elementowa tablica jest indeksowana od 0 do n-1. Zawsze wykorzystuj indeksowanie tylko z tymi wskaźnikami, które przechowują adresy tablic. |
Nigdy nie zapisuj ani nie odczytuj elementów spoza końca tablicy. Nigdy nie myl tablicy wskaźników ze wskaźnikiem do tablicy. |
Łańcuch to ciąg znaków. Dotychczas wykorzystywaliśmy tylko stale łańcuchy. Jednym z nich był:
cout « "Hello world!\n"
W C++ łańcuch jest reprezentowany przez tablicę znaków zakończoną wartością zero. Możesz zadeklarować łańcuch tak jak każdą tablicę. Np.:
char Czesc[]={ ’H' , 'e' , •!' , , 'o' ,1 'W , 'o' , 'r', '1', 'd', '\0' };
Rodzina jest wskaźnikiem do tablicy na stercie. Kiedy w linii 33 odwołujemy się do wskaźnika pKot, to wstawiamy do tablicy obiekt klasy KOT (dlaczego nie? tablica znajduje się przecież na stercie). Ale pKot jest w następnej iteracji wykorzystywany do stworzenia kolejnego obiektu. Czy nie pojawia się tutaj niebezpieczeństwo utraty wskaźników do obiektów w tablicy?
Byłby to wielki problem, gdyby nie fakt, że skasowanie wskaźnika Rodzina (za pomocą delete) zwolni całą pamięć zarezerwowaną dla tablicy. Kompilator potrafi usunąć każdy obiekt z tablicy i zwolnić zajmowaną pamięć.
Żeby się o tym przekonać, zmień w liniach 26, 29 i 36 rozmiar tablicy z 500 na 10 i usuń komentarz z linii 21. Uruchom program, a przekonasz się, że w momencie jego zakończenia zostanie wywołany destruktor każdego ze stworzonych obiektów. Jeśli tworzysz obiekt za pomocą new to zawsze musisz go usunąć za pomocą delete. Podobnie, gdy tworzysz tablicę z wykorzystaniem new <klasa>[rozmiar], to kasujesz ją potem za pomocą delete [ ]. Nawiasy są informacją dla kompilatora, że skasowaniu ma ulec cała tablica.
Jeśli pominąłbyś nawiasy, to usunięty zostałby tylko pierwszy element tablicy. Możesz to sprawdzić. Usuń nawiasy w linii 39 i komentarz w linii 21. Po uruchomieniu programu zobaczysz, że destruktor zostanie wywołany tylko jeden raz. Gratulacje! Właśnie ubyło Ci pamięci!
ZAWSZE |
NIGDY |
Zawsze pamiętaj, że n elementowa tablica jest indeksowana od 0 do n-1. Zawsze wykorzystuj indeksowanie tylko z tymi wskaźnikami, które przechowują adresy tablic. |
Nigdy nie zapisuj ani nie odczytuj elementów spoza końca tablicy. Nigdy nie myl tablicy wskaźników ze wskaźnikiem do tablicy. |
Łańcuch to ciąg znaków. Dotychczas wykorzystywaliśmy tylko stale łańcuchy. Jednym z nich był:
cout « "Hello world!\n"
W C++ łańcuch jest reprezentowany przez tablicę znaków zakończoną wartością zero. Możesz zadeklarować łańcuch tak jak każdą tablicę. Np.:
char Czesc[]={'H',’e’,,’1','o',' 'W','o’,'r’,'1',’d','\0' };