190 Godzina 13
_________ Płytkie kopiowanie polega na skopiowaniu wartości zmiennych obiektu
źródłowego do obiektu tworzonego. Jeśli w obiekcie występują wskaźniki to w efekcie końcowym otrzymamy dwa obiekty, w których te wskaźniki wskazują na tę samą pamięć. Wskaźników nie należy kopiować bezpośrednio. Należy wykonać kopie wartości przechowywanych pod adresami przez nie wskazywanymi do nowego obszaru pamięci.
Jeśli klasa KOT będzie zawierać zmienną jegoWiek wskazującą na wartość typu
int na stercie, to konstruktor kopiujący skopiuje wartość tej zmiennej (czyli adres w niej zawarty) do zmiennej jegoWiek obiektu tworzonego. Oba wskaźniki będą wskazywać na ten sam obszar pamięci, tak jak pokazano na rysunku 13.1.
Takie rozwiązanie spowoduje katastrofę, gdy jeden z obiektów zostanie usunięty z pamięci. Zostanie wtedy wywołany destruktor klasy KOT, który zwolni zarezerwowaną na stercie pamięć.
Załóżmy, że z pamięci zostanie usunięty oryginalny obiekt KOT. Destruktor zwolni zarezerwowaną pamięć. Jednak kopia nadal będzie wskazywać na ten obszar. Jeśli będziesz próbował dostać się do tej pamięci to twój program przestanie działać... jeśli będziesz miał szczęście. Rysunek 13.2. ilustruje opisaną sytuację.
Sterta | ||||||
-► |
5 | |||||
oryginalny |
nowy KOT | |||||
KOT | ||||||
jegoWiek |
jegoWiek |
Wykorzystanie
domyślnego
konstruktora
kopiującego
Powstawanie
błędnego
wskaźnika
Rozwiązaniem tego problemu jest napisanie własnego konstruktora kopiującego i rezerwacja pamięci we własnym zakresie. Jeśli pamięć zostanie zarezerwowana, to wartości z oryginalnego obiektu (w szczególności te wskazywane przez wskaźniki) mogą zostać do niej skopiowane. Takie kopiowanie nazywamy głębokim. Ilustruje to listing 13.3.
Płytkie kopiowanie polega na skopiowaniu wartości zmiennych obiektu źródłowego do obiektu tworzonego. Jeśli w obiekcie występują wskaźniki to w efekcie końcowym otrzymamy dwa obiekty, w których te wskaźniki wskazują na tę samą pamięć. Wskaźników nie należy kopiować bezpośrednio. Należy wykonać kopie wartości przechowywanych pod adresami przez nie wskazywanymi do nowego obszaru pamięci.
NOWY TERMIN
Jeśli klasa KOT będzie zawierać zmienną jegoWiek wskazującą na wartość typu int na stercie, to konstruktor kopiujący skopiuje wartość tej zmiennej (czyli adres w niej zawarty) do zmiennej jegoWiek obiektu tworzonego. Oba wskaźniki będą wskazywać na ten sam obszar pamięci, tak jak pokazano na rysunku 13.1.
Takie rozwiązanie spowoduje katastrofę, gdy jeden z obiektów zostanie usunięty z pamięci. Zostanie wtedy wywołany destruktor klasy KOT, który zwolni zarezerwowaną na stercie pamięć.
Załóżmy, że z pamięci zostanie usunięty oryginalny obiekt KOT. Destruktor zwolni zarezerwowaną pamięć. Jednak kopia nadal będzie wskazywać na ten obszar. Jeśli będziesz próbował dostać się do tej pamięci to twój program przestanie działać... jeśli będziesz miał szczęście. Rysunek 13.2. ilustruje opisaną sytuację.
Wykorzystanie
domyślnego
konstruktora
kopiującego
Powstawanie
błędnego
wskaźnika
Rozwiązaniem tego problemu jest napisanie własnego konstruktora kopiującego i rezerwacja pamięci we własnym zakresie. Jeśli pamięć zostanie zarezerwowana, to wartości z oryginalnego obiektu (w szczególności te wskazywane przez wskaźniki) mogą zostać do niej skopiowane. Takie kopiowanie nazywamy głębokim. Ilustruje to listing 13.3.