198 Godzina 14
198 Godzina 14
ANALIZA:
Implementacja operatora ++, zawarta w liniach 26-30, została zmieniona tak, że zwraca aktualny obiekt za pomocą pośredniego odwołania do this. Dzięki temu możemy wykonać operację przypisania w linii 40. Jeśli obiekt klasy Licznik rezerwowałby pamięć, to trzeba by było również napisać własny konstruktor kopiujący, uwzględniający to. Jednak w tym konkretnym przypadku domyślny konstruktor kopiujący jest całkowicie wystarczający.
Zauważ, że wartość zwracana jest referencją do obiektu klasy Licznik, przez co unikamy zbędnego tworzenia kopii obiektu. Jest ona zadeklarowana jako const, ponieważ wartość nie powinna być zmieniona przez funkcje wykorzystującą ten obiekt.
Co zrobić, jeśli chcesz przeciążyć operator przyrostkowy? Pojawia się tutaj pewien problem. Jak rozróżnić oba operatory - przedrostkowy i przyrostkowy? Przyjęta została konwencja, że w przypadku deklaracji operatora przyrostkowego (postfix) podaje się parametr całkowity (patrz listing 14.3). Wartość tego parametru jest ignorowana, stanowi on jedynie sygnał dla kompilatora.
Zanim zaczniemy przeciążać operatory przyrostkowe i przedrostkowe musimy poznać różnicę miedzy nimi. W skrócie: operator przedrostkowy najpierw inkrementuje zmienną, a potem zwraca jej wartość, operator przyrostkowy odwrotnie, najpierw zwraca wartość, a potem inkrementuje zmienną.
0 ile operator przyrostkowy może zwiększyć wartość i zwrócić obiekt przez wartość (tak jak w listingu 14.2), to operator przedrostkowy musi zwrócić wartość przed inkrementacją. W tym celu trzeba stworzyć pomocniczy obiekt, przechowujący początkową wartość obiektu przed inkrementacją. Zwrócić należy ten chwilowy obiekt.
Spójrzmy na to wszystko z innej strony. Jeśli napiszesz: a * x++;
1 x było równe 5, to po wykonaniu tej instrukcji a będzie równe 5 i x będzie równe 6. Dzieje się tak dlatego, że zwracamy wartość x i przypisujemy ją do a. Jeśli x jest obiektem, to jego operator przyrostkowy musi przechować oryginalną wartość x w obiekcie pomocniczym, zwiększyć x i zwrócić obiekt pomocniczy.
Pamiętaj jednak, że zwracając obiekt pomocniczy nie można go zwrócić przez referencję gdyż jest to obiekt lokalny. Koniecznie trzeba go zwrócić przez wartość.
Listing 14.3 demonstruje sposób przeciążania i wykorzystania operatora przyrostkowego i przedrostkowego.
Implementacja operatora ++, zawarta w liniach 26-30, została zmieniona tak, że zwraca aktualny obiekt za pomocą pośredniego odwołania do this. Dzięki temu możemy wykonać operację przypisania w linii -10. Jeśli obiekt klasy Licznik rezerwowałby pamięć, to trzeba by było również napisać własny konstruktor kopiujący, uwzględniający to. Jednak w tym konkretnym przypadku domyślny konstruktor kopiujący jest całkowicie wystarczający.
ANALIZA
Zauważ, że wartość zwracana jest referencją do obiektu klasy Licznik, przez co unikamy zbędnego tworzenia kopii obiektu. Jest ona zadeklarowana jako const, ponieważ wartość nie powinna być zmieniona przez funkcje wykorzystującą ten obiekt.
Co zrobić, jeśli chcesz przeciążyć operator przyrostkowy? Pojawia się tutaj pewien problem. Jak rozróżnić oba operatory - przedrostkowy i przyrostkowy? Przyjęta została konwencja, że w przypadku deklaracji operatora przyrostkowego (postfix) podaje się parametr całkowity (patrz listing 14.3). Wartość tego parametru jest ignorowana, stanowi on jedynie sygnał dla kompilatora.
Zanim zaczniemy przeciążać operatory przyrostkowe i przedrostkowe musimy poznać różnicę miedzy nimi, W skrócie: operator przedrostkowy najpierw inkrementuje zmienną, a potem zwraca jej wartość, operator przyrostkowy odwrotnie, najpierw zwraca wartość, a potem inkrementuje zmienną.
0 ile operator przyrostkowy może zwiększyć wartość i zwrócić obiekt przez wartość (tak jak w listingu 14.2), to operator przedrostkowy musi zwrócić wartość przed inkrementacją. W tym celu trzeba stworzyć pomocniczy obiekt, przechowujący początkową wartość obiektu przed inkrementacją. Zwrócić należy ten chwilowy obiekt. Spójrzmy na to wszystko z innej strony. Jeśli napiszesz:
a = x++;
1 x było równe 5, to po wykonaniu tej instrukcji a będzie równe 5 i x będzie równe 6. Dzieje się tak dlatego, że zwracamy wartość x i przypisujemy ją do a. Jeśli x jest obiektem, to jego operator przyrostkowy musi przechować oryginalną wartość x w obiekcie pomocniczym, zwiększyć x i zwrócić obiekt pomocniczy.
Pamiętaj jednak, że zwracając obiekt pomocniczy nie można go zwrócić przez referencję gdyż jest to obiekt lokalny. Koniecznie trzeba go zwrócić przez wartość. Listing 14.3 demonstruje sposób przeciążania i wykorzystania operatora przyrostkowego i przedrostkowego.