Konstruktor (programowanie obiektowe): Różnice pomiędzy wersjami

[wersja nieprzejrzana][wersja nieprzejrzana]
Usunięta treść Dodana treść
Linia 63:
====Kopiowanie obiektu ''składnik po składniku''====
W większości przypadków kopiowanie obiektu ''składnik po składniku'' jest tym, czego oczekuje użytkownik klasy i nie ma potrzeby definiowania własnej wersji konstruktora kopiującego. Jednak nie zawsze takie działanie jest pożądane (przykład w C++):
siałatakiego baba makhuja xD
: Klasa <code>MojaKlasa</code> zawiera pole <code>wsk</code> będące wskaźnikiem na zmienną typu <code>int</code>. Każdy obiekt tej klasy ma posiadać własną zmienną typu <code>int</code> którą wskazuje wskaźnik <code>wsk</code>. W kodzie programu znajduje się deklaracja obiektu klasy <code>MojaKlasa</code> gdzie następuje wywołanie zdefiniowanego konstruktora, a w nim rezerwacja pamięci na zmienną typu int i przypisanie jej adresu do wskaźnika. Następnie, w celu sprawdzenia wartości, wyświetlana jest wartość zmiennej wskazywanej przez wskaźnik z utworzonego obiektu, wartość jest równa <code>5</code>. Następnie tworzony jest drugi obiekt klasy o nazwie <code>kopiaObiektu</code> za pomocą niejawnie wygenerowanego konstruktora kopiującego, konstruktor ten kopiuje wszystkie pola klasy ''składnik po składniku''. W kolejnym kroku przypisywana jest wartość <code>3</code> zmiennej wskazywanej przez wskaźnik obiektu <code>kopiaObiektu</code>. Następnie wyświetlana jest ponownie wartość zmiennej wskazywanej przez wskaźnik obiektu <code>obiektMojejKlasy</code> (gdzie wcześniej była wartość <code>5</code>). Okazuje się, że teraz znajduje się tam wartość <code>3</code>, oba obiekty wskazują na tę samą zmienną, a w założeniach każdy obiekt miał mieć własną zmienną. Problem wynikł z tego, że nie zdefiniowano konstruktora kopiującego. Kopiowanie ''składnik po składniku'' w tym przypadku okazało się rozwiązaniem niezgodnym ze wcześniejszymi założeniami, ponieważ została skopiowana wartość wskaźnika, a nie została utworzona nowa zmienna, do której wskazanie powinno być umieszczone we wskaźniku. W efekcie otrzymaliśmy 2 obiekty wskazujące na ten sam obiekt w pamięci i modyfikacja w jednym z nich miała swój efekt w drugim. Jeszcze większy problem pojawi się w trakcie zakończania programu. Niszczenie pierwszego z dwóch obiektów przebiegnie prawidłowo, destruktor drugiego zwalnianego obiektu będzie wykonywał operację zwolnienia już zwolnionej pamięci, co spowoduje błąd. Aby uzyskać działanie klasy zgodnie z założeniami, należy zaimplementować w klasie MojaKlasa własną wersję konstruktora kopiującego:
// ...