Wykład 6
Funkcje wirtualne
Szablony funkcji
Programowanie obiektowe
1
Szablony funkcji
Szablony klas
Funkcje wirtualne
Polimorfizm jest obsługiwany przez język C++ zarówno na etapie
kompilacji (przeciążanie funkcji i operatorów), jak i na etapie wykonania
(dziedziczenie i funkcje wirtualne)
Funkcja wirtualna to metoda składowa zadeklarowana w klasie bazowej
a zdefiniowana w klasie pochodnej
Programowanie obiektowe
2
a zdefiniowana w klasie pochodnej
Aby utworzyć funkcję wirtualną należy jej deklaracje w klasie bazowej
poprzedzić słowem kluczowym virtual
Zasadę, pozwalającą funkcjom wirtualnym realizować polimorfizm
określamy w skrócie jako „jeden interfejs, wiele metod”
W klasie bazowej ma miejsce definicja intejfejsu; każda definicja funkcji
wirtualnej w klasie pochodnej to implementacja funkcji specyficznych dla
danej klasy pochodnej
Funkcje wirtualne
Przykład (jeden interfejs, dwie metody):
konwersja litrów na galony i temperatury w stopniach Fahrenheita na
stopnie Celsjusza z wykorzystaniem funkcji wirtualnych
Programowanie obiektowe
3
Program 5.1
Funkcje wirtualne
Funkcję wirtualną można wywoływać w „normalny sposób”, tzn.
wykorzystując nazwę obiektu i operator kropki
Do wskazywania obiektów klas pochodnych można wykorzystać wskaźnik
ich klasy bazowej
Wówczas kompilator C++ decyduje o wyborze wersji funkcji na podstawie
typu obiektu wskazywanego przez ten wskaźnik; wybór odbywa się na
etapie wykonania programu
Programowanie obiektowe
4
etapie wykonania programu
Oznacza to, że wskazanie różnych obiektów spowoduje wskazanie różnych
wersji funkcji wirtualnej
Przykład
Program 5.2
Funkcje wirtualne
Atrybut virtual jest dziedziczony
Oznacza to, że bez względu na to, ile razy jest dziedziczona funkcja
wirtualna pozostaje funkcją wirtualną
Przykład
Program 5.3
Programowanie obiektowe
5
Program 5.3
Funkcje wirtualne
Funkcje wirtualne są hierarchiczne
Funkcja zadeklarowana w klasie bazowej jako virtual może być
przesłonięta (tj. przedefiniowana) w klasie pochodnej, ale nie musi być tak
zawsze
Jeśli w klasie pochodnej funkcja wirtualna nie zostanie przesłonięta, wtedy
obiekty tej klasy odwołujące się do takiej funkcji wirtualnej będą
wykorzystywały funkcję zdefiniowana w klasie bazowej
Programowanie obiektowe
6
wykorzystywały funkcję zdefiniowana w klasie bazowej
Przykład
Program 5.4
Szablony (funkcji i klas)
Synonimy: szablon funkcji, funkcja szablonowa, funkcja ogólna
Szablony są jedną z najbardziej wyrafinowanych i najbardziej efektywnych
cech języka C++
Zostały dodane do specyfikacji języka zaledwie kilka lat temu
Dzięki szablonom możliwe jest tworzenie tzw. ogólnych definicji funkcji
i klas
W ogólnych funkcjach lub klasach typ danych, na których operuje funkcja
Programowanie obiektowe
7
W ogólnych funkcjach lub klasach typ danych, na których operuje funkcja
lub klasa jest określany jako parametr
W konsekwencji można stworzyć funkcję lub klasę, przystosowaną do pracy
z kilkoma różnymi typami danych, bez konieczności jawnego
redefiniowania specyfikacji dla poszczególnych typów
Funkcja może być zatem w pewnym stopniu inteligentna: może
samodzielnie dobrać zarówno typ argumentów, jak typ wyniku samej
funkcji!
Szablony funkcji
Funkcję ogólną (szablon funkcji) tworzymy posługując się słowem
kluczowym template
template <class Ttype > typ_zwracany nazwa_funkcji(lista parametrów)
{
// ciało funkcji
}
Programowanie obiektowe
8
}
gdzie:
Ttype – symboliczna nazwa typu danych wykorzystywanych przez
funkcję (podczas wywołania funkcji kompilator zamienia ten typ na
rzeczywisty typ danych)
class - słowo kluczowe konieczne, aby powstał szablon;
Uwaga:
Jeśli parametrów szablonu jest więcej niż jeden, to po przecinku
powtarzamy słowo class i podajemy kolejną nazwę parametru;
Funkcje ogólne są podobne do funkcji przeciążonych, ale podczas pracy
z nimi obowiązuje więcej ograniczeń
W odróżnieniu od funkcji przeciążonej funkcja ogólna musi we wszystkich
wersjach wykonywać te same operacje (tyle, że na zmiennych różnych
typów)
Nazwa szablonu musi być zdefiniowana w zakresie globalnym, czyli na
zewnątrz wszystkich funkcji i klas.
Szablony funkcji
Programowanie obiektowe
9
zewnątrz wszystkich funkcji i klas.
Parametr szablonu musi wystąpić jako typ argumentu funkcji definiowanej
tym szablonem.
Parametrem szablonu funkcji może być typ obiektu czyli nazwa klasy.
Definicja szablonu nie powoduje jeszcze utworzenia funkcji szablonowej.
Zostanie ona utworzona dopiero po wystąpieniu w kodzie nazwy tej funkcji
(wywołaniu). Utworzenie odbędzie się zgodnie z „recepturą” zapisaną w
szablonie.
Nazwa funkcji ogólnej nie powinna pokrywać się z innymi nazwami
zmiennych i funkcji globalnych.
Parametr szablonu – nazwany podczas deklarowania szablonu – nie musi
mieć tej samej nazwy podczas definiowania szablonu.
Dwa szablony o takiej samej nazwie mogą wystąpić w tym samym kodzie;
należy tylko uważać, aby jeden nie był szczególnym przypadkiem drugiego
Szablony funkcji
Programowanie obiektowe
10
należy tylko uważać, aby jeden nie był szczególnym przypadkiem drugiego
(wówczas linker nie wiedziałby, z którego ma skorzystać)
Szablon wstawiając do wzorca funkcji różne typy argumentów realizuje tak
naprawdę przeciążenie nazwy funkcji.
Sam szablon też może być przeciążony czyli w tym samym zakresie
ważności może wystąpić dwa lub kilka razy z tą sama nazwą, ale różnymi
parametrami, np.:
Szablony funkcji
Programowanie obiektowe
11
template <class TypSymb> void funkcja (TypSymb, int);
template <class TypSymb > void funkcja (TypSymb, int, float, char);
Szablon jest deklarowany globalnie, ale stosowany lokalnie; dlatego nie
powinien używać nazw zmiennych globalnych
UWAGA: szablony ciągle są nowością: w różnych środowiskach języka
C++, a szczególnie w zakresie pracy linkerów mogą występować problemy
Szablony funkcji
Programowanie obiektowe
12
C++, a szczególnie w zakresie pracy linkerów mogą występować problemy
W szablonie możemy stosować kwalifikatory inline, extern, static.
Pamiętajmy jednak, że słowo to odnosi się ostatecznie nie do szablonu ale
do funkcji, która wg tego szablonu zostanie zbudowana:
Przykład
template <class bb> inline bb wieksza (bb z1, bb z2)
{
return (z1>z2)? z1:z2;
}
Sortowanie przez zamianę (bąbelkowe)
44
Klucze
pocz
ą
tkowe
55
i = 2
i = 3
i = 5
i = 4
44
06
06
06
K r o k i a l g o r y t m u
12
12
06
12
06
12
i = 6
06
12
i = 7
06
12
i = 8
Programowanie obiektowe
13
42
18
06
94
67
12
42
18
94
67
12
55
55
18
94
42
67
44
44
55
42
18
67
94
44
55
42
18
67
94
44
55
42
18
67
94
44
55
42
18
67
94
44
55
42
18
67
94
Szablony funkcji
Funkcje ogólne (szablony funkcji) są bardzo użyteczne
Można je stosować w tych sytuacjach, kiedy różne funkcje wykorzystują
ten sam ogólny algorytm
Programowanie obiektowe
14
Przykład: funkcja ogólna, realizująca sortowanie bąbelkowe
Program 5.5
Szablony klas
Oprócz funkcji ogólnych (szablonów funkcji) w języku C++ można także
definiować szablony klas (klasy ogólne)
W takim przypadku tworzona klasa zawiera definicje wszystkich
wykorzystywanych przez nią algorytmów, jednak typ danych, na których
Programowanie obiektowe
15
wykorzystywanych przez nią algorytmów, jednak typ danych, na których
klasa operuje, zostanie przekazany do niej jako parametr dopiero w chwili
tworzenia obiektów
Szablony klas
Ogólna składnia szablonu klasy:
template <class Ttype > class nazwa_klasy
{
// ciało klasy
}
Programowanie obiektowe
16
gdzie Ttype oznacza nazwę typu, który zostanie określony podczas tworzenia
obiektu (egzemplarza klasy)
Można zdefiniować więcej niż jeden typ ogólny: wówczas kolejne typy są
oddzielane od siebie przecinkami trzeba powtarzać słowo class);
Po utworzeniu klasy ogólnej można stworzyć obiekt (egzemplarz klasy),
posługując się składnią:
nazwa_klasy <typ_rzeczywisty> nazwa_obiektu;
Szablony klas
Przykład 1: szablon klasy: stos ogólny
Przykład 2: szablon klasy z dwoma typami ogólnymi
Program 5.6
Programowanie obiektowe
17
Przykład 2: szablon klasy z dwoma typami ogólnymi
Program 5.7
Szablony klas
Przeciążanie operatora []
Program 5.8
Program 5.9
Programowanie obiektowe
18
Przykład 3: szablon klasy: ogólna, bezpieczna tablica
Program 5.10
Szablony klas
W szablonach klas można posługiwać się także argumentami, które nie
służą do określenia typu
Składnia szablonu, w przypadku użycia takiego parametru nie ulega zmianie
Programowanie obiektowe
19
Program 5.11
Szablony klas
W szablonach klas można definiować argumenty domyślne, związane z
typem ogólnym, np.
template <class X=int> class MojaKlasa( ...
Dopuszcza się także definiowanie wartości domyślnych dla argumentów nie
służących do określania typu
Wartość domyślna jest wykorzystywana wtedy, gdy podczas tworzenia
obiektu (egzemplarza klasy) żadna wartość nie zostanie wyspecyfikowana w
Programowanie obiektowe
20
obiektu (egzemplarza klasy) żadna wartość nie zostanie wyspecyfikowana w
sposób jawny
Wartości domyślne dla argumentów nie służących do określania typu
definiuje się w taki sam sposób, jak dla standardowych argumentów funkcji
Przykład
Program 5.12
Programowanie obiektowe
21