1 / 23

Virtuális függvények (late binding)

Virtuális függvények (late binding). Ficsor Lajos Miskolci Egyetem Általános Informatikai Tanszék. Azonos nevű függvények megkülönböztetése. paraméterszignatúra (függvény overloading) - egy hatáskörön belül SCOPE operátor segítségével (classname::fname)

isi
Download Presentation

Virtuális függvények (late binding)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Virtuális függvények(late binding) Ficsor Lajos Miskolci Egyetem Általános Informatikai Tanszék Virtuális függvények

  2. Azonos nevű függvények megkülönböztetése • paraméterszignatúra (függvény overloading) - egy hatáskörön belül • SCOPE operátor segítségével (classname::fname) • mezőkiválasztó operátor (objname.fname) Ez a megkülönböztetés fordítási időben megtörténik. Származtatás: gond lehet az azonos nevű függvényekkel. Megoldás:late binding (késői kötés) Nyelvi eszköz:virtuális függvény Virtuális függvények

  3. CPPEX12.C class jarmu { protected: int kerekek; double suly; public: jarmu (int k, double s) {kerekek = k; suly = s;} void hanykerek (void) { cout << "A jarmu kerekeinek szama: " << kerekek << "\n";} }; Virtuális függvények

  4. CPPEX12.C (folyt.) class gepkocsi : public jarmu { protected: int szemelyek; public: gepkocsi (int k, double s, int szem) : jarmu (k, s) { szemelyek = szem; } void hanykerek (void) { cout << "A gepkocsi kerekeinek szama: " << kerekek << "\n";} }; Virtuális függvények

  5. CPPEX12.C (folyt.) main () { jarmu bicikli (2,15); bicikli.hanykerek(); gepkocsi trabant (4, 120.0, 4); trabant.hanykerek(); } // Az eremeny: // A jarmu kerekeinek szama: 2 // A gepkocsi kerekeinek szama: 4 Virtuális függvények

  6. CPPEX12.C - tanulságok A tagfüggvény meghívása objektumhoz kapcsolva • az objektum osztálya határozza meg a hatáskört, amelyben a függvény definíciót keresni kell • a fordítóprogram azonosítani tudja a függvényt • a megfelelő függvény hívódik meg Virtuális függvények

  7. CPPEX13.C main ()// A CPPEX12 osztalydefiniciojaval { jarmu *kerekes; kerekes = new jarmu (2,15.); kerekes->hanykerek(); kerekes = new gepkocsi (4, 120.0, 4); kerekes->hanykerek(); } // Az eredmeny: // A jarmu kerekeinek szama: 2 // A jarmu kerekeinek szama: 4 Virtuális függvények

  8. CPPEX13.C - tanulságok A tagfüggvény meghívása objektumra mutató pointer segítségével • a pointer alaptípusa határozza meg az osztályt, amelynek hatáskörében a függvény definíciót keresni kell • a fordítóprogramazonosítani tudja a függvényt • nem a megfelelő függvény hívódik meg, ha a pointer alaptípusa és az általa megcímzett objektum típusa eltér Virtuális függvények

  9. Virtuális függvény: formai szabályok • Csak tagfüggvény definiálható virtuálisnak, az osztálydeklaráció törzsében elhelyezett virtualalapszóval. • Az öröklődési hierarchiában lejjebb álló osztályok tartalmazhatnak ugyanilyen nevű, paraméter szignatúrájú és visszatérési értékű tagfügvényeket. • Ezek a függvények a virtual alapszó nélkül is virtuálisnak minősülnek. Virtuális függvények

  10. Formai szabályok (folyt.) • A virtuális függvényt a bázisosztályban köteleződefiniálni, a leszármazottak mindegyikében nem. • A bázisosztályban a virtuális függvény lehet valódi virtuális függvény - ekkor 0-val kell inicializálni. Például: virtual void hanykerek () = 0; • Az ilyen osztály nem példányosítható (absztrakt osztály). Virtuális függvények

  11. Formai szabályok (folyt.) • Ha mutatón keresztül hívjuk meg a virtuális függvényt, nem a mutató alaptípusa határozza meg, hogy melyik változatot kell használni, hanem a megcímzett objektum típusa. • A megcímzett objektum típusa általában csak futási időben derül ki • A fordítóprogram általában nem tudja megkeresni a meghívandó függvényt, csak előkészíteni a futásidejű kiválasztását. Virtuális függvények

  12. Virtuális függvény használata Használata: • ugyanolyan funkciók a leszármazott osztályokban • a funkció implementációja osztályfüggő Virtuális függvények

  13. Virtuális függvény korai kötéssel Az alábbi esetekben a virtuális függvény hívását is fel tudja dolgozni a fordítóprogram fordítási időben (korai kötés): • Objektum hivatkozáson keresztül hívjuk meg. • SCOPE operátorral explicite meghatározzuk a definíció helyét. • A bázisosztály konstruktorában vagy destruktorában hívjuk meg. Virtuális függvények

  14. CPPEX14.C class jarmu { protected: int kerekek; double suly; public: jarmu (int k, double s) {kerekek = k; suly = s;} virtual void hanykerek (void) { cout << "A jarmu kerekeinek szama: " << kerekek << "\n";} }; Virtuális függvények

  15. CPPEX14.C (folytatás) class gepkocsi : public jarmu { protected: int szemelyek; public: gepkocsi (int k, double s, int szem) : jarmu (k, s) { szemelyek = szem; } void hanykerek (void) { cout << "A gepkocsi kerekeinek szama: " << kerekek << "\n";} }; Virtuális függvények

  16. CPPEX14.C (folytatás) main () { jarmu *kerekes; kerekes = new jarmu (2,15.); kerekes->hanykerek(); delete kerekes; // Ha precizek akarunk // lenni kerekes = new gepkocsi (4, 120.0, 4); kerekes->hanykerek(); } // Az eredmeny: // A jarmu kerekeinek szama: 2 // A gepkocsi kerekeinek szama: 4 Virtuális függvények

  17. Példa: grafikus elemek, 1. verzió Virtuális függvények

  18. Példa: grafikus elemek 1. verzió (folyt.) Implementációk: void Point::MoveTo(int NewX, int NewY) { Hide(); // aktuális törlése X = NewX; // új pozíció Y = NewY; Show(); // megjelenítés az új helyen }; void Circle::MoveTo(int NewX, int NewY) { Hide(); // aktuális törlése X = NewX; // új pozíció Y = NewY; Show(); // megjelenítés az új helyen }; Virtuális függvények

  19. Példa: grafikus elemek 1. verz. (folyt.) A két implementáció azonosnak tűnik, mert azonos az algoritmus. A különbség: • a Point::MoveTo-ban a Point::Hide() hívódik meg • a Circle::MoveTo-ban a Circle::Hide() hívódik meg Ezért nem örökölhető a MoveTo (azaz külön implementáció szükséges minden osztályra)! Virtuális függvények

  20. Példa: grafikus elemek 2. verzió Location X : Integer Y : Integer GetX() : Integer GetY() : Integer Point Visible : Boolean <<virtual>>Show() <<virtual>> Hide() MoveTo(NewX : Integer, NewY : Integer) IsVisible() : Boolean Circle Radius : Integer Hide() Show() Expand(Ratio : Single) Ellipse Square Radius1 : Integer Hide() Virtuális függvények Show() Show() Hide() Expand(Ratio : Single)

  21. Példa: grafikus elemek 2. verzió (folyt.) Különbségek: • a Show és Hide függvények virtuálisak • a MoveTo függvény öröklődik Eredmény: • a MoveTo függvény a this->Showés this->Hide függvényeket hívja meg • a this mutató által megcímzett objektum típusa (amellyel a MoveTo-t használtuk) dönt • az objektum aktuális típusa csak futásidőben dől el Virtuális függvények

  22. Példa a használatra const int MAXELEM=100; Location* elemek[MAXELEM]; int aktElemszam=0; // Uj rajzelem letrehozasa aktElemszam++; elemek[aktElemszam] = new …… Virtuális függvények

  23. Példa a használatra (folyt.) // Osszes elem ujra rajzolasa for (int i=0; i<aktElemszam; i++) elemek[i] -> Show(); Virtuális függvények

More Related