C++ Polimorfizmus példával
Miben rejlik a polimorfizmus? C++?
In C++, a polimorfizmus egy tagfüggvény eltérő viselkedését okozza az azt meghívó/meghívó objektumtól függően. A polimorfizmus egy görög szó, ami annyit jelent, hogy sok alakja van. Ez akkor fordul elő, ha az osztályok hierarchiája öröklődés útján kapcsolódik.
Tegyük fel például, hogy a makeSound() függvényünk van. Amikor egy macska meghívja ezt a funkciót, nyávog hangot ad ki. Amikor egy tehén ugyanazt a funkciót hívja meg, a nyírás hangját adja.
Bár egy funkciónk van, másképpen viselkedik különböző körülmények között. A függvénynek számos formája van; így polimorfizmust értünk el.
A polimorfizmus típusai
C++ kétféle polimorfizmust támogat:
- Fordítási idejű polimorfizmus, és
- Futásidejű polimorfizmus.
Fordítsa össze az időpolimorfizmust
A túlterhelt függvényeket az argumentumok számának és típusának egyeztetésével hívhatja meg. Az információ a fordítási idő alatt jelen van. Ez azt jelenti, hogy a C++ A fordító a fordításkor kiválasztja a megfelelő függvényt.
A fordítási idejű polimorfizmus a funkciók túlterhelésével és a kezelő túlterhelésével érhető el.
Funkció túlterhelés
A függvénytúlterhelés akkor fordul elő, ha sok hasonló nevű, de eltérő argumentumú függvényünk van. Az argumentumok számuk vagy típusuk szerint különbözhetnek.
Példa 1
#include <iostream> using namespace std; void test(int i) { cout << " The int is " << i << endl; } void test(double f) { cout << " The float is " << f << endl; } void test(char const *ch) { cout << " The char* is " << ch << endl; } int main() { test(5); test(5.5); test("five"); return 0; }
output:
Itt van egy képernyőkép a kódról:
Kód magyarázata:
- Szerelje be az iostream fejlécfájlt a kódunkba. Használni tudjuk majd a funkcióit.
- Szerelje be az std névteret a kódunkba. Az osztályait használhatjuk anélkül, hogy meghívnánk.
- Hozzon létre egy teszt nevű függvényt, amely egy i egész paramétert vesz fel. A { jelzi a funkcióteszt törzsének kezdetét.
- A fenti funkcióteszt meghívása/meghívása esetén végrehajtandó utasítás.
- A fenti funkcióteszt törzsének vége.
- Hozzon létre egy teszt nevű függvényt, amely egy f lebegő paramétert vesz fel. A { jelzi a funkcióteszt törzsének kezdetét.
- A fenti funkcióteszt meghívása/meghívása esetén végrehajtandó utasítás.
- A fenti funkcióteszt törzsének vége.
- Hozzon létre egy teszt nevű függvényt, amely egy ch karakterparamétert vesz fel. A { jelzi a funkcióteszt törzsének kezdetét.
- A fenti funkcióteszt meghívása/meghívása esetén végrehajtandó utasítás.
- A fenti funkcióteszt törzsének vége.
- Hívja meg a main() függvényt. A { a függvény törzsének kezdetét jelöli.
- Hívja meg a függvénytesztet, és adja meg az 5-öt az argumentum értékeként. Ez meghívja az egész argumentumot elfogadó tesztfüggvényt, azaz az első tesztfüggvényt.
- Hívja meg a függvénytesztet, és adja át neki az 5.5-öt az argumentum értékeként. Ez meghívja a lebegő argumentumot elfogadó tesztfüggvényt, vagyis a második tesztfüggvényt.
- Hívja meg a függvénytesztet, és adjon át neki ötöt az argumentum értékeként. Ez meghívja a karakter argumentumot elfogadó tesztfüggvényt, azaz a harmadik tesztfüggvényt.
- A programnak értéket kell visszaadnia, ha sikeresen fut.
- A main() függvény törzsének vége.
Három függvényünk van azonos névvel, de különböző típusú argumentumokkal. Elértük a polimorfizmust.
Operator Túlterhelés
In Operator Túlterhelés, új jelentést definiálunk a C++ operátor. Ez megváltoztatja a kezelő működését is. Például megadhatjuk a + operátort két karakterlánc összefűzésére. Úgy ismerjük, mint a számértékek összeadásának operátorát. A definíciónk után egész számok közé helyezve összeadja őket. A karakterláncok közé helyezve összefűzi őket.
Példa 2
#include<iostream> using namespace std; class ComplexNum { private: int real, over; public: ComplexNum(int rl = 0, int ov = 0) { real = rl; over = ov; } ComplexNum operator + (ComplexNum const &obj) { ComplexNum result; result.real = real + obj.real; result.over = over + obj.over; return result; } void print() { cout << real << " + i" << over << endl; } }; int main() { ComplexNum c1(10, 2), c2(3, 7); ComplexNum c3 = c1+c2; c3.print(); }
output:
Itt van egy képernyőkép a kódról:
Kód magyarázata:
- Szerelje be az iostream fejlécfájlt a programunkba, hogy használni tudja a funkcióit.
- Szerelje be az std névteret a programunkba, hogy az osztályait hívás nélkül használhassa.
- Hozzon létre egy ComplexNum nevű osztályt. A { az osztálytörzs kezdetét jelöli.
- A privát hozzáférés módosítóval jelölje meg a változókat privátként, vagyis csak az osztályon belülről lehet hozzáférni.
- Határozzon meg két egész változót, valós és over.
- Használja a nyilvános hozzáférés módosítót a konstruktor nyilvánosként való megjelölésére, ami azt jelenti, hogy az a konstrukción kívülről is elérhető lesz osztály.
- Hozzuk létre az osztálykonstruktort és inicializáljuk a változókat.
- Inicializálja a real változó értékét.
- Inicializálja a változó értékét over.
- A kivitelező test vége.
- Felül kell írnunk a + operátor jelentését.
- Hozzon létre egy ComplexNum típusú adattípus eredményt.
- Komplex számokhoz használja a + operátort. Ez a sor hozzáadja egy szám valós részét egy másik szám valós részéhez.
- Komplex számokhoz használja a + operátort. Ez a sor hozzáadja egy szám képzeletbeli részét egy másik szám képzeletbeli részéhez.
- A program sikeres végrehajtás után visszaadja az eredmény változó értékét.
- Vége a + operátor új jelentésének definíciójának, vagyis a túlterhelésnek.
- Hívja meg a print() metódust.
- Nyomtassa ki az új komplex számot, miután hozzáadta a konzolon.
- A print() függvény törzsének vége.
- A ComplexNum osztály törzsének vége.
- Hívja meg a main() függvényt.
- Adja át mind a valós, mind az összetett részek értékeit. A c1 első része hozzáadódik a c2 első részéhez, azaz a 10+3. A c1 második része hozzáadódik c második részéhez, azaz 2+7.
- Végezzen műveletet a túlterhelt + operátorral, és az eredményt a c3 változóban tárolja.
- Nyomtassa ki a c3 változó értékét a konzolon.
- A main() függvény törzsének vége.
Futásidejű polimorfizmus
Ez akkor fordul elő, ha egy objektum metódusát futás közben hívják meg, nem pedig fordítási idő alatt. A futásidejű polimorfizmus a függvény felülbírálásával érhető el. A meghívandó/meghívandó függvény futás közben jön létre.
Funkció felülbírálása
A függvény felülbírálása akkor történik, ha az alaposztály egy függvénye új definíciót kap egy származtatott osztályban. Ekkor azt mondhatjuk, hogy az alapfunkciót felülírták.
Például:
#include <iostream> using namespace std; class Mammal { public: void eat() { cout << "Mammals eat..."; } }; class Cow: public Mammal { public: void eat() { cout << "Cows eat grass..."; } }; int main(void) { Cow c = Cow(); c.eat(); return 0; }
output:
Itt van egy képernyőkép a kódról:
Kód magyarázata:
- A funkcióinak használatához importálja az iostream fejlécfájlt programunkba.
- Szerelje be az std névteret a programunkba, hogy az osztályait hívás nélkül használhassa.
- Hozz létre egy Mammal nevű osztályt. A { az osztálytörzs kezdetét jelöli.
- A nyilvános hozzáférés módosító segítségével állítsa be nyilvánosan elérhetővé a létrehozandó funkciót. Az osztályon kívülről is elérhető lesz.
- Hozzon létre egy nyilvános függvényt eat. A { a függvénytörzs kezdetét jelöli.
- Nyomtassa ki a cout függvényhez adott utasítást az eat() függvény meghívásakor.
- Az eat() függvény törzsének vége.
- Az emlős osztály testének vége.
- Hozzon létre egy Cow nevű osztályt, amely örökli az Emlős osztályt. A tehén a származtatott osztály, míg az emlős az alaposztály. A { az osztály kezdetét jelzi.
- A nyilvános hozzáférés módosító segítségével jelölje meg nyilvánosan elérhetőként a létrehozandó funkciót. Az osztályon kívülről is elérhető lesz.
- Az alaposztályban definiált eat() függvény felülírása. A { a függvénytörzs kezdetét jelöli.
- A függvény meghívásakor a konzolra nyomtatandó utasítás.
- Az eat() függvény törzsének vége.
- Vége az osztály testének Tehén.
- Hívja meg a main() függvényt. A { jelöli a függvény törzsének kezdetét.
- Hozzon létre egy példányt a Cow osztályból, és adja meg a nevet c.
- Hívja meg a Cow osztályban definiált eat() függvényt.
- A programnak értéket kell visszaadnia a sikeres befejezés után.
- A main() függvény vége.
C++ Virtuális funkció
A virtuális függvény egy másik módja a futásidejű polimorfizmus megvalósításának C++. Ez egy speciális függvény, amely egy alaposztályban van definiálva, és újradefiniálható a származtatott osztályban. Virtuális függvény deklarálásához a virtuális kulcsszót kell használni. A kulcsszónak meg kell előznie a függvény deklarációját az alaposztályban.
Ha egy virtuális függvényosztály öröklődik, a virtuális osztály újradefiniálja a virtuális függvényt, hogy megfeleljen az igényeinek. Például:
#include <iostream> using namespace std; class ClassA { public: virtual void show() { cout << "The show() function in base class invoked..." << endl; } }; class ClassB :public ClassA { public: void show() { cout << "The show() function in derived class invoked..."; } }; int main() { ClassA* a; ClassB b; a = &b; a->show(); }
output:
Itt van egy képernyőkép a kódról:
Kód magyarázata:
- Szerelje be az iostream fejlécfájlt a kódba a funkcióinak használatához.
- Szerelje be az std névteret a kódunkba, hogy az osztályait hívás nélkül használhassa.
- Hozzon létre egy osztályt ClassA néven.
- A nyilvános hozzáférés módosító segítségével jelölje meg egy osztálytagot nyilvánosan elérhetőként.
- Hozzon létre egy show() nevű virtuális függvényt. Nyilvános funkció lesz.
- A show() meghívásakor nyomtatandó szöveg. A endl egy C++ kulcsszó, ami végsort jelent. Az egérkurzort a következő sorra mozgatja.
- A show() virtuális függvény törzsének vége.
- Az A osztály törzsének vége.
- Új osztály létrehozása ClassB néven, amely örökli az ClassA osztályt. Az A osztály lesz az alaposztály, míg a B osztály lesz a származtatott osztály.
- A nyilvános hozzáférés módosító segítségével jelölje meg egy osztálytagot nyilvánosan elérhetőként.
- Határozza meg újra az alaposztályból származó show() virtuális függvényt.
- A konzolra nyomtatandó szöveg a származtatott osztályban definiált show() függvény meghívásakor.
- A show() függvény törzsének vége.
- A származtatott osztály törzsének vége, ClassB.
- Hívja meg a main() függvényt. A program logikáját hozzá kell adni a törzséhez.
- Hozzon létre egy mutatóváltozót a néven. A ClassA nevű osztályra mutat.
- Hozzon létre egy példányt az osztályból ClassB néven. A példány neve b.
- Rendelje hozzá a tárolt értékeket a b címben az a változóban.
- A származtatott osztályban definiált show() függvény meghívása. A késői kötés végrehajtásra került.
- A main() függvény törzsének vége.
Fordítási idő polimorfizmus vs. Futásidejű polimorfizmus
Íme a fő különbségek a kettő között:
Compile-time polimorfizmus | Futásidejű polimorfizmus |
---|---|
Korai kötődésnek vagy statikus polimorfizmusnak is nevezik | Ezt késői/dinamikus kötésnek vagy dinamikus polimorfizmusnak is nevezik |
A metódus a fordítási idő alatt kerül meghívásra/meghívásra | A metódust futás közben hívja/meghívja |
Funkció túlterheléssel és kezelő túlterheléssel valósítható meg | Metódusfelülíráson és virtuális függvényeken keresztül valósul meg |
Példa, módszer túlterhelés. Sok módszernek lehet hasonló neve, de eltérő számú vagy típusú argumentum | Példa, módszer felülbírálása. Sok módszernek hasonló neve és prototípusa lehet. |
Gyorsabb végrehajtás, mivel a metódusok felfedezése a fordítási idő alatt történik | Lassabb végrehajtás, mivel a metódusfelderítő futás közben történik. |
Less rugalmasság biztosított a problémamegoldáshoz, mivel a fordítási idő alatt minden ismert. | Nagy rugalmasság biztosított az összetett problémák megoldásához, mivel a módszereket futás közben fedezik fel. |
Összegzésként
- A polimorfizmus azt jelenti, hogy sok formája van.
- Ez akkor fordul elő, ha az osztályok hierarchiája öröklődik.
- A polimorfizmus esetén egy függvény eltérően viselkedhet attól függően, hogy melyik objektum hívja meg.
- A fordítási idejű polimorfizmusban a meghívandó függvény a fordítási idő alatt jön létre.
- A futásidejű polimorfizmusban a meghívandó függvény futás közben jön létre.
- A fordítási idejű polimorfizmust a függvény túlterhelése és a kezelő túlterhelése határozza meg.
- A függvénytúlterhelésben sok hasonló nevű, de eltérő argumentumú függvény létezik.
- A paraméterek számban vagy típusban különbözhetnek.
- A kezelő túlterhelése esetén új jelentést határoznak meg C++ üzemeltetők.
- A futásidejű polimorfizmus a függvény felülbírálásával érhető el.
- A függvény felülbírálásánál egy származtatott osztály új definíciót ad az alaposztályban definiált függvénynek.