16.05.2015 Views

Programowanie w C++ Borland Builder - Wyższa Szkoła Informatyki ...

Programowanie w C++ Borland Builder - Wyższa Szkoła Informatyki ...

Programowanie w C++ Borland Builder - Wyższa Szkoła Informatyki ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

wirtualnej w taki sposób, funkcja we wszystkich "pokoleniach"<br />

musi mieć taki sam prototyp, tj. pobierać taką samą liczbę<br />

parametrów tych samych typów oraz zwracać wartość tego samego<br />

typu. Jeśli tak się nie stanie, <strong>C++</strong> potraktuje różne prototypy<br />

tej samej funkcji w kolejnych pokoleniach zgodnie z zasadami<br />

overloadingu funkcji. Zwróćmy tu uwagę, że w przypadku funkcji<br />

wirtualnych o wyborze wersji funkcji decyduje to, wobec którego<br />

obiektu (której klasy) funkcja została wywołana. Jeśli wywołamy<br />

funkcję dla obiektu Ciapek, <strong>C++</strong> wybierze wersję<br />

CZwierzak::Oddychaj(), natomiast wobec obiektu Sardynka zostanie<br />

zastosowana wersja CRybka::Oddychaj().<br />

W <strong>C++</strong> wskaźnik do klasy bazowej może także wskazywać na klasy<br />

pochodne, więc zastosowanie funkcji wirtualnych może dać pewne<br />

ciekawe efekty "uboczne". Jeśli zadeklarujemy wskaźnik *p do<br />

obiektów klasy bazowej CZwierzak *p; a następnie zastosujemy ten<br />

sam wskaźnik do wskazania na obiekt klasy pochodnej:<br />

p = &Ciapek; p->Oddychaj();<br />

...<br />

p = &Sardynka; p->Oddychaj();<br />

zarządamy w taki sposób od <strong>C++</strong> rozpoznania właściwej wersji<br />

wirtualnej metody Oddychaj() i jej wywołania we właściwym<br />

momencie. <strong>C++</strong> może rozpoznać, którą wersję funkcji należałoby<br />

zastosować tylko na podstawie typu obiektu, wobec którego<br />

funkcja została wywołana. I tu pojawia się pewien problem.<br />

Kompilator wykonując kompilcję programu nie wie, co będzie<br />

wskazywał pointer. Ustawienie pointera na konkretny adres<br />

nastąpi dopiero w czasie wykonania programu (run-time).<br />

Kompilator "wie" zatem tylko tyle:<br />

p->Oddychaj()(); //która wersja Oddychaj() ???<br />

Aby mieć pewność, co w tym momencie będzie wskazywał pointer,<br />

kompilator musiałby wiedzieć w jaki sposób będzie przebiegać<br />

wykonanie programu. Takie wyrażenie może zostać wykonane "w<br />

ruchu programu" dwojako: raz, gdy pointer będzie wskazywał<br />

Ciapka (inaczej), a drugi raz - Sardynkę (inaczej):<br />

CZwierzak *p;<br />

...<br />

for(p = &Ciapek, int i = 0; i < 2; i++)<br />

{<br />

p->Oddychaj();<br />

p = &Sardynka;<br />

}<br />

lub inaczej:<br />

if(p == &Ciapek) CZwierzak::Oddychaj();<br />

else CRybka::Oddychaj();<br />

- 340-

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!