Wykład 5-6
Konstruktory kopiujące
Klasy zaprzyjaznione
Wskaznik this
Przecią\anie operatorów
Funkcje wirtualne
Szablony funkcji
Szablony klas
Programowanie obiektowe
1
Konstruktor kopiujący
Jedną z najwa\niejszych postaci konstruktorów przecią\onych są tzw.
konstruktory kopiujące
Taki konstruktor tworzy kopię innego, ju\ istniejącego wśród obiektów
danej klasy
Ogólna postać deklaracji konstruktora kopiującego:
klasa::klasa(klasa& obiekt);
lub
klasa::klasa(const klasa& obiekt);
Pozostałe argumenty konstruktora (jeśli występują) są domyślne.
Przykłady deklaracji konstruktorów kopiujących:
X::X(X&);
lub
X::X(X&, float=3.1415, int=0);
Programowanie obiektowe
2
Konstruktor kopiujący
Konstruktorem kopiującym w danej klasie jest konstruktor, który mo\na
wywołać z jednym argumentem typu referencja obiektu danej klasy:
klasa::klasa(klasa &)
klasa::klasa(const klasa &)
Konstruktor kopiujący wprowadza obiekty identyczne z ju\ istniejącymi,
czyli ich kopie (konstruowanie obiektu na podstawie wzoru).
Konstruktor kopiujący mo\e być wywołany niejawnie:
1. W sytuacji gdy do funkcji jest przekazywany przez wartość obiekt
klasy X. Wówczas tworzona jest kopia tego obiektu.
2. W sytuacji kiedy funkcja zwraca przez wartość obiekt klasy X.
Wtedy tak\e tworzona jest kopia obiektu.
To, \e konstruktor kopiujący podaje obiekt kopiowany przez referencję daje
mu mo\liwość zmiany zawartości obiektu klasy!!
Programowanie obiektowe
3
Konstruktor kopiujący
Nie mo\na pominąć referencji w konstruktorze kopiującym, bo gdyby
konstruktor X wywoływał obiekty swojej klasy X przez wartość, czyli
wytwarzałby swoją kopię, to powstaje nie zamknięta pętla tworzenia kopii.
Konstruktor kopiujący mo\e uszkodzić oryginał!!
Zabezpieczamy się przed taką sytuacją następująco:
X::X(const X& obiekt)
Teraz konstruktor X wie, \e obiekt klasy X jest jest typu const, czyli nie
mo\e zmienić sam siebie.
Programowanie obiektowe
4
Konstruktor kopiujący
Przykład programowy
Program 4.5
Programowanie obiektowe
5
Funkcje zaprzyjaznione
Są to takie funkcje, które mimo, \e nie są składnikami klasy mają dostęp do
jej składników czyli innych funkcji i zmiennych danej klasy
Mają dostęp tak\e do tych składników klasy, które są hermetyzowane
etykietą private
Funkcja zaprzyjazniona jest wprowadzana słowem kluczowym friend
Sposób stosowania:
class figura{
int x,y;
& & .
friend void goniec(figura f)
};
Programowanie obiektowe
6
Funkcje zaprzyjaznione
Funkcja goniec(figura f) jest zdefiniowana gdzieś w programie w całkowicie
innym miejscu i nie jest funkcją składową klasy figura
W klasie figura {} chcemy z niej skorzystać nawet, jeśli przynale\y ona do
innej klasy (wtedy poprawnie jest taką funkcję umieścić w sekcji public w jej
klasie).
Cechy funkcji zaprzyjaznionych:
Funkcja mo\e być zaprzyjazniona z kilkoma klasami
Na argumentach jej wywołania mo\e wykonywać operacje zgodnie ze
swoją definicją
Mo\e być napisana w zupełnie innym języku ni\ C++ i dlatego mo\e
nie być funkcją składową klasy.
Programowanie obiektowe
7
Funkcje zaprzyjaznione
Poniewa\ funkcja typu friend nie jest składnikiem klasy, to nie ma
wskaznika this czyli musi się posłu\yć operatorem jawnego wskaznika lub
przypisania, aby wykonać działania (tak\e te na składniku klasy, z którą jest
zaprzyjazniona).
Jest deklarowana w klasie ze słowem kluczowym friend i nie podlega
etykietom hermetyzacji (public, private, protected)
Mo\e być cała zdefiniowana w klasie i wtedy jest typu inline, ale nadal jest
funkcją zaprzyjaznioną.
Nie musi być funkcją składową \adnej klasy, ale mo\e nią być
Programowanie obiektowe
8
Funkcje zaprzyjaznione
Klasa mo\e się przyjaznić z wieloma funkcjami, które są lub nie są
składnikami innych klas;
Funkcje zaprzyjaznione nie są przechodnie, czyli zaprzyjaznienie nie
przenosi się z klasy do klasy, tzn. zaprzyjaznienie nie podlega
mechanizmowi dziedziczenia (w tym przypadku przyjaciel mojego
przyjaciela nie jest moim przyjacielem );
Z zasady umieszcza się funkcje zaprzyjaznione na początku wszystkich
deklaracji w klasie;
Dopuszcza się stosowanie słowa kluczowego friend do definiowania klas
zaprzyjaznionych; w takim przypadku wszystkie funkcje składowe klasy
zaprzyjaznionej mają dostęp do prywatnych składników drugiej klasy.
Programowanie obiektowe
9
Funkcje i klasy zaprzyjaznione
Przykład programowy
Program 4.6
Program 4.7
Programowanie obiektowe
10
Wskaznik this
Podczas wywoływania funkcji składowej jest do niej automatycznie
przekazywany niejawny wskaznik do obiektu, na rzecz którego realizowane
jest wywołanie funkcji; wskaznik ten nazywa się this
Przykład
Program 4.8
Funkcja musi odszukać obiekt, aby wykonać operację na jego rzecz. Robi to
tak, \e korzysta z ukrytego wskaznika this, który jest inicjowany w
momencie pojawienia się operatora kropki po nazwie obiektu.
Ten wskaznik pokazuje funkcji na którym egzemplarzu (konkrecie)
obiektów klasy ma wykonać swoje czynności.
Programowanie obiektowe
11
Wskaznik this
pwr::pwr(double base, int exp)
{
b = base;
e = exp;
val = 1;
if(exp==0) return;
for( ; exp>0; exp--) val = val * b;
}
pwr::pwr(double base, int exp)
{
this->b = base;
this->e = exp;
this->val = 1;
if(exp==0) return;
for( ; exp>0; exp--)
this->val = this->val * this->b;
}
Programowanie obiektowe
12
Referencje
Język C++ posiada dodatkową cechę związana ze wskaznikami - referencję;
Zasadniczo referencja to niejawny wskaznik;
Mo\na ja wykorzystywać na trzy sposoby:
1) jako parametr funkcji,
2) jako zwracaną wartość,
3) jako zmienną referencyjną.
Programowanie obiektowe
13
Referencje jako parametry
W momencie wywołania funkcji jej parametry mogą być przekazywane na
dwa sposoby: przez wartość i przez referencję;
Podczas przekazywania parametru przez wartość do funkcji przekazywana
jest kopia argumentu;
Przykład:
Program 4.9a
Programowanie obiektowe
14
Referencje jako parametry
Wa\nym zastosowaniem referencji jest mo\liwość definiowania funkcji,
wykorzystujących mechanizm przekazywania parametrów przez referencję;
Przekazywanie przez referencję polega na przekazaniu do funkcji wskaznika
do argumentu; mo\na to realizować na dwa sposoby:
jawne przekazanie wskaznika do parametru;
posłu\enie się się tzw. parametrem referencyjnym;
Programowanie obiektowe
15
Referencje jako parametry
Przykład jawnego przekazania wskaznika do parametru
Program 4.9
Przykład u\ycia parametru referencyjnego
Program 4.10
Programowanie obiektowe
16
Przekazywanie obiektów przez referencję
Przekazywanie obiektu jako argumentu funkcji polega na przekazaniu jego
kopii;
Po zakończeniu funkcji kopia jest niszczona i wywoływany jest destruktor
tej kopii;
Jeśli nie chcemy, aby destruktor był uaktywniany, mo\emy przekazać
obiekt do funkcji przez referencję;
Podczas przekazywania obiektu przez referencję kopia obiektu nie jest
tworzona (w konsekwencji nie ma jej niszczenia i nie jest wywoływany
destruktor obiektu);
Przykład
c:
Program 4.11
Programowanie obiektowe
17
Zwracanie referencji
Funkcja mo\e zwracać referencję;
W konsekwencji funkcja mo\e występować z lewej strony instrukcji
przypisania!
Przykład
Program 4.12
Programowanie obiektowe
18
Zmienne referencyjne
Referencję mo\na zastosować jako samodzielna zmienną;
Zmienna referencyjna jest tworzona jako nowa nazwa dla istniejącej
zmiennej (przezwisko);
Podczas tworzenia zmiennej referencyjnej obowiązkowa jest jej inicjacja;
Przykład
Program 4.13
Programowanie obiektowe
19
Przecią\anie operatorów
Z przecią\aniem funkcji ściśle związane jest zagadnienie przecią\ania operatorów
W języku C++ mo\na przecią\yć większość operatorów tak, aby wykonywały
zadania charakterystyczne dla danej klasy, np. dla klasy stos operator + mo\e być
wykorzystany do dodawania elementu na stos, a operator do zdejmowania
elementu ze stosu
Po przecią\eniu odpowiednich operatorów mo\na posługiwać się obiektami w
wyra\eniach tak samo jak zmiennymi typów wbudowanych
Operator mo\na przecią\yć tworząc funkcję operatora
Funkcja operatora definiuje, jakie operacje na obiektach wskazanej klasy ma
wykonywać operator
Do tworzenia funkcji operatora słu\y słowo kluczowe operator
Funkcja operatora mo\e, ale nie musi, być składową klasy
Funkcje operatora nie będące składowymi klasy są najczęściej jej funkcjami
zaprzyjaznionymi
Programowanie obiektowe
20
Przecią\anie operatorów
Ogólna składnia funkcji operatora, będącej składową klasy:
zwracany_typ nazwa_klasy::operator # (lista_argumentów)
{
symbol operatora
//operacje
}
Lista argumentów mo\e być pusta (w przypadku operatorów
jednoargumentowych)
Przykład
Program 5.1
Programowanie obiektowe
21
Przecią\anie operatorów
// Przecią\enie operatora + dla klasy loc
loc loc::operator+(loc op2) {
loc temp;
temp.longitude = op2.longitude + longitude;
temp.latitude = op2.latitude + latitude;
return temp;
}
int main() {
loc ob1(10, 20), ob2( 20, 30);
ob1.show(); // wyświetla 10 20
ob2.show(); // wyświetla 20 30
ob1 = ob1 + ob2;
operand przekazywany przez parametr op2
...
operand przekazywany przez wskaznik this
Programowanie obiektowe
22
Przecią\anie operatorów
W kolejnym programie przykładowym przecią\one zostaną trzy operatory
dwuargumentowe (+, -, =) oraz jeden operator jednoargumentowy (++)
w formie przedrostkowej
Przykład
Program 5.2
Programowanie obiektowe
23
Operatory przyrostowe - przypomnienie
Przykład
#include
using namespace std;
int main(void) {
int i, j;
i = 10;
// Najpierw przypisanie, potem inkrementacja
j = i++;
/* wyświetlenie wartości zmiennych i oraz j */
cout << "i=" << i;
cout << ", j=" << j;
getchar(); // Zatrzymanie okna konsoli
return 0;
}
Program 5.3
Programowanie obiektowe
24
Operatory przyrostowe - przypomnienie
Przykład
#include
using namespace std;
int main(void) {
int i, j;
i = 10;
j = ++i;
// Najpierw inkrementacja, potem przypisanie
/* Wyświetlenie wartości zmiennych i oraz j */
cout << "i=" << i;
cout << ", j=" << j;
getchar(); // Zatrzymanie okna konsoli
return 0;
Program 5.4
}
Programowanie obiektowe
25
Formy przedrostkowe i przyrostkowe przecią\onych operatorów
inkrementacji i dekrementacji
Inkrementacja w formie przedrostkowej
typ operator++() {
// ciało operatora w formie przedrostkowej
}
Inkrementacja w formie przyrostkowej
typ operator++(int x) {
// ciało operatora w formie przyrostkowej
}
Dekrementacja w formie przedrostkowej
typ operator- -() {
- -
- -
- -
// ciało operatora w formie przedrostkowej
}
Dekrementacja w formie przyrostkowej
typ operator- -(int x) {
- -
- -
- -
Program 5.2a
// ciało operatora w formie przyrostkowej
}
Programowanie obiektowe
26
Przecią\anie operatorów za pomocą funkcji zaprzyjaznionych
Operator mo\na przecią\yć tak\e posługując się funkcjami nie będącymi
składowymi klasy
W tym celu najczęściej stosuje się funkcje zaprzyjaznione
Funkcje zaprzyjaznione nie są składowymi klasy, nie jest więc do nich
przekazywany wskaznik this
Dlatego do zaprzyjaznionej funkcji operatora operandy przekazywane są w
sposób jawny
Oznacza to, \e funkcja zaprzyjazniona słu\ąca do przecią\ania operatora
dwuargumentowego ma dwa parametry, a funkcja zaprzyjazniona
przecią\ająca operator jednoargumentowego ma jeden parametr
Podczas przecią\ania operatora dwuargumentowego za pomocą funkcji
zaprzyjaznionej lewy operand przekazywany jest jako pierwszy, a prawy
jako drugi
Przykład
Program 5.5
Programowanie obiektowe
27
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
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
Programowanie obiektowe
28
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ć wskaznik
ich klasy bazowej
Wówczas kompilator C++ decyduje o wyborze wersji funkcji na podstawie
typu obiektu wskazywanego przez ten wskaznik; wybór odbywa się na
etapie wykonania programu
Oznacza to, \e wskazanie ró\nych obiektów spowoduje wskazanie ró\nych
wersji funkcji wirtualnej
Przykład
Program 6.1
Programowanie obiektowe
29
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 6.2
Programowanie obiektowe
30
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
Przykład
Program 6.3
Programowanie obiektowe
31
Funkcje wirtualne
Przykład: konwersja litrów na galony i temperatury w stopniach Fahrenheita
na stopnie Celsjusza z wykorzystaniem funkcji wirtualnych
Program 6.4
Programowanie obiektowe
32
Szablony
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
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!
Programowanie obiektowe
33
Szablony funkcji
Funkcję ogólną (szablon funkcji) tworzymy posługując się słowem
kluczowym template
template typ_zwracany nazwa_funkcji(lista parametrów)
{
// ciało funkcji
}
gdzie:
Ttype symboliczna nazwa typu danych, wykorzystywanych przez
funkcję (podczas tworzenia konkretnej wersji 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 dla słowo class i podajemy kolejną nazwę parametru;
Programowanie obiektowe
34
Szablony funkcji
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.
Parametr szablonu musi wystąpić jako typ argumentu funkcji definiowanej
tym szablonem.
WNIOSEK: nie mo\na wprost zadać szablonem funkcji o typie innym ni\
typ jej argumentów; jest to mo\liwe poprzez specjalne obejście ograniczeń
języka.
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. Utworzenie odbędzie się zgodnie z recepturą zapisaną w
szablonie.
Programowanie obiektowe
35
Szablony funkcji
Nazwa funkcji szablonowej nie powinna pokrywać się z innymi nazwami
zmiennych i funkcji globalnych.
Operacja zapisana w funkcji poddana jest takim samym regułom na
poprawność operacji jak we wszystkich innych funkcjach, czyli nie wykona
się na przykład operacja arytmetyczna na zmiennych znakowych.
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
(wówczas linker nie wiedziałby, z którego ma skorzystać)
Programowanie obiektowe
36
Szablony funkcji
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.:
template void funkcja (typ, int);
template void funkcja (typ, int, float, char);
Programowanie obiektowe
37
Szablony funkcji
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
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 inline bb wieksza (bb z1, bb z2)
{
return (z1>z2)? z1:z2;
}
Programowanie obiektowe
38
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
Przykład: funkcja ogólna, realizująca sortowanie bąbelkowe
Program 6.7
Programowanie obiektowe
39
Sortowanie przez zamianę (bąbelkowe)
K r o k i a l g o r y t m u
Klucze
i = 2 i = 3 i = 4 i = 5 i = 6 i = 7 i = 8
początkowe
44 06 06 06 06 06 06 06
55 44 12 12 12 12 12 12
12 55 44 18 18 18 18 18
42 12 55 44 42 42 42 42
94 42 18 55 44 44 44 44
18 94 42 42 55 55 55 55
06 18 94 67 67 67 67 67
67 67 67 94 94 94 94 94
Programowanie obiektowe
40
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
klasa operuje, zostanie przekazany do niej jako parametr dopiero w chwili
tworzenia obiektów
Programowanie obiektowe
41
Szablony klas
Ogólna składnia szablonu klasy:
template class nazwa_klasy
{
// ciało klasy
}
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;
Po utworzeniu klasy ogólnej mo\na stworzyć obiekt (egzemplarz klasy),
posługując się składnią:
nazwa_klasy nazwa_obiektu;
Programowanie obiektowe
42
Szablony klas
Przykład 1: szablon klasy: stos ogólny
Program 6.8
Przykład 2: szablon klasy z dwoma typami ogólnymi
Program 6.9
Programowanie obiektowe
43
Szablony klas
Przecią\anie operatora []
Program 6.10a
Program 6.10b
Przykład 3: szablon klasy: ogólna, bezpieczna tablica
Program 6.10
Programowanie obiektowe
44
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
Program 6.11
Programowanie obiektowe
45
Szablony klas
W szablonach klas mo\na definiować argumenty domyślne, związane z
typem ogólnym, np.
template 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
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 6.12
Programowanie obiektowe
46
Programowanie obiektowe
47
Wyszukiwarka
Podobne podstrony:
PO W3 II ZIN
PO W1 2 II ZIN
PO W3 II ZIN
PO W7 8 II ZIN
PO W4 II ZIN
02 Stalinizacja życia w Polsce po II Wojnie Światowej
Zimna wojna, konferencje, sprawa niemiec po II wojnie swiatowej
Świat po II Wojnie Światowej, prezentacja
Świat po II Wojnie Światowej
Świat po II Wojnie Światowej (2) test
ustalenie granic polski po ii wojnie światowej (2)
Kształtowanie się polskiej i żydowskiej wizji martyrologicznej po II wojnie światowej
Gospodarki panstw Europy Zach po II wojnie swiatowej
Rozwój i użycie broni minowej na przykładzie wybranych wojen oraz konfliktów lokalnych po II wś
więcej podobnych podstron