Fragment notatki:
Przeładowywanie operatorów, dziedziczenie Wykład 6 09/11/09 2 Przeładowywane operatorów Jest bardzo wygodną metodą, zamiast definiować funkcje typu add itp. możemy użyć odpowiednich operatorów Przeładowanie operatora dokonuje się definiując własną funkcję o nazwie operatorX , gdzie X oznacza symbol interesującego nas operatora Może być funkcją składową Może być globalną funkcją Lista operatorów, które można przeładowywać +, -, *, /, %, ^, &, |, ~, ! , =, , +=, -=, *=, /=, %=, ^=, &=, |=, , =, =, &&, ||, ++, --, ‘,’ , -*, -, new, delete, () , [] Natomiast następujące operatory nie mogą być przeładowywane ., .*, ::, ?: 09/11/09 3 Przeładowywane operatorów... Nie można wymyślać swoich operatorów Nie można zmieniać priorytetów operatorów Nie można też zmienić argumentowości operatorów, czyli tego czy są jedno- czy dwuargumentowe Nie można również zmieniać łączności operatorów Dla każdej klasy następujące operatory są generowane automatycznie = , & (jednoargumentowy – pobranie adresu), new , , , delete 09/11/09 4 Funkcja operatorowa jako funkcja składowa Jeżeli definiujemy składową funkcje operatorową to przyjmuje ona zawsze o jeden mniej argument niż ta sam funkcja napisana w postaci funkcji globalnej Funkcja ta nie może być typu static , bo w jej działaniu bierze udział wskaźnik this Nie mogą istnieć dwie funkcje operatorowe pracujące na tych samych argumentach (zdefiniowane jako funkcja globalna i funkcja składowa) W tym wypadku po lewej stronie operatora zawsze musi stać obiekt klasy, dla której ten operator jest zdefiniowany Obiekt1 + Obiekt2; Obiekt1.operator+(Obiekt2); Przykład cpp_6.1 09/11/09 5 Funkcja operatorowa jako funkcja globalna Nie musi być funkcją zaprzyjaźnioną Jeżeli wymaga dostępu do zmiennych prywatnych to musi być zaprzyjaźniona Dzięki globalnym funkcjom operatorowym można zdefiniować operatory do klas już istniejących np. bibliotecznych W przypadku takich klas muszą one udostępniać odpowiedni interfejs (w szczególności dostęp do składowych) Nie ma takiego ograniczenia jak dla funkcji operatorowej zdefiniowanej jako metoda Przykład cpp_6.2 09/11/09 6 Przemienność Funkcja operatorowa będąca funkcją składową klasy wymaga, aby obiekt stojący po lewej stronie operatora był obiektem tej klasy
(…)
…
(zdefiniowany i nieprywatny) to wygenerowany operator
przypisania dla klasy pochodnej skorzysta z niego
Jeżeli klasa zawiera jakiś składnik const lub będący
referencją to operator przypisania nie jest generowany
automatycznie
Wtedy musimy stworzyć taki operator samemu
Tak jak przy zwykłej klasie nie ma sensu definiować
operatora przypisania jeżeli zostanie on
wygenerowany przez kompilator i będzie działał…
…; //Błąd
Zwykła funkcja globalna nie ma tego ograniczenia
09/11/09
CFraction operator*(int i, CFraction K);
//Argumenty mogą być w odwrotnej kolejności
Oczywiście przy wywołaniach z niezgodnością typów muszą być
zdefiniowane odpowiednie konwersje
6
Operatory, które muszą być
funkcjami składowymi
Operator przypisania =
Generowany automatyczne przez kompilator, tak że
przepisuje obiekt składnik po składniku
Nie jest generowany automatycznie w sytuacjach
Jeżeli klasa ma składnik const
Jeżeli klasa ma składnik będący referencją
Jeżeli klasa ma składową klasę, w której operator przypisanie
jest prywatny
Jeżeli klasa ma klasę podstawową z prywatnym operatorem
przypisania
Nie jest dziedziczony
Na ogół zawiera
Nie zawsze dobry – wskaźniki
Cześć destruktorową
Cześć konstruktorową
Przykład cpp_6.3
09/11/09
7
Operatory które muszą być
funkcjami składowymi...
Operator []
Przeładowany operator [] powinien mieć działanie
podobne do działanie w stosunku do typów wbudowanych
Z tego powodu powinien być zadeklarowany
klasa& klasa::operator[](unsigned i);
czyli zwracać referencję do pojedynczego elementu tablicy
o indeksie i
Możliwe będzie wtedy wykonanie
a = tab[i];
tab…
…[i] = a;
Przykład cpp_6.3a
09/11/09
8
Operatory które muszą być
funkcjami składowymi...
Operator ()
Może przyjmować dowolną liczbę parametrów
Może posłużyć do indeksowanie wielowymiarowych tablic
tab(1,2,3);
Może też upraszczać zapis, nie musimy wywoływać funkcji
tylko wystarczy sam operator ()
Bardzo przydatny operator przy wykorzystaniu funktorów z
algorytmami STL
Operator ->
09/11/09
Rzadko…
…
wygenerowany automatycznie ten operator (będzie
kopiował składnik po składniku)
Destruktor
09/11/09
Ale w częściowo inteligentny sposób, tzn. jeśli w klasie
podstawowej jest ten operator zdefiniowany to zostanie użyty
Często unieważnia działanie konstruktorów, przez co jeśli
konstrukotry nie są dziedziczone to destruktor też
19
Dziedziczenie wielopokoleniowe
Nie ma ograniczeń w tworzeniu kolejnych…
... zobacz całą notatkę
Komentarze użytkowników (0)