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.

Polimorfizmus be C++

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.

A polimorfizmus típusai

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:

Funkció túlterhelés

Itt van egy képernyőkép a kódról:

Funkció túlterhelés

Kód magyarázata:

  1. Szerelje be az iostream fejlécfájlt a kódunkba. Használni tudjuk majd a funkcióit.
  2. Szerelje be az std névteret a kódunkba. Az osztályait használhatjuk anélkül, hogy meghívnánk.
  3. 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.
  4. A fenti funkcióteszt meghívása/meghívása esetén végrehajtandó utasítás.
  5. A fenti funkcióteszt törzsének vége.
  6. 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.
  7. A fenti funkcióteszt meghívása/meghívása esetén végrehajtandó utasítás.
  8. A fenti funkcióteszt törzsének vége.
  9. 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.
  10. A fenti funkcióteszt meghívása/meghívása esetén végrehajtandó utasítás.
  11. A fenti funkcióteszt törzsének vége.
  12. Hívja meg a main() függvényt. A { a függvény törzsének kezdetét jelöli.
  13. 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.
  14. 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.
  15. 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.
  16. A programnak értéket kell visszaadnia, ha sikeresen fut.
  17. 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:

Operator Túlterhelés

Itt van egy képernyőkép a kódról:

Operator Túlterhelés

Operator Túlterhelés

Kód magyarázata:

  1. Szerelje be az iostream fejlécfájlt a programunkba, hogy használni tudja a funkcióit.
  2. Szerelje be az std névteret a programunkba, hogy az osztályait hívás nélkül használhassa.
  3. Hozzon létre egy ComplexNum nevű osztályt. A { az osztálytörzs kezdetét jelöli.
  4. 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.
  5. Határozzon meg két egész változót, valós és over.
  6. 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.
  7. Hozzuk létre az osztálykonstruktort és inicializáljuk a változókat.
  8. Inicializálja a real változó értékét.
  9. Inicializálja a változó értékét over.
  10. A kivitelező test vége.
  11. Felül kell írnunk a + operátor jelentését.
  12. Hozzon létre egy ComplexNum típusú adattípus eredményt.
  13. 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.
  14. 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.
  15. A program sikeres végrehajtás után visszaadja az eredmény változó értékét.
  16. Vége a + operátor új jelentésének definíciójának, vagyis a túlterhelésnek.
  17. Hívja meg a print() metódust.
  18. Nyomtassa ki az új komplex számot, miután hozzáadta a konzolon.
  19. A print() függvény törzsének vége.
  20. A ComplexNum osztály törzsének vége.
  21. Hívja meg a main() függvényt.
  22. 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.
  23. Végezzen műveletet a túlterhelt + operátorral, és az eredményt a c3 változóban tárolja.
  24. Nyomtassa ki a c3 változó értékét a konzolon.
  25. 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:

Funkció felülbírálása

Itt van egy képernyőkép a kódról:

Funkció felülbírálása

Kód magyarázata:

  1. A funkcióinak használatához importálja az iostream fejlécfájlt programunkba.
  2. Szerelje be az std névteret a programunkba, hogy az osztályait hívás nélkül használhassa.
  3. Hozz létre egy Mammal nevű osztályt. A { az osztálytörzs kezdetét jelöli.
  4. 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.
  5. Hozzon létre egy nyilvános függvényt eat. A { a függvénytörzs kezdetét jelöli.
  6. Nyomtassa ki a cout függvényhez adott utasítást az eat() függvény meghívásakor.
  7. Az eat() függvény törzsének vége.
  8. Az emlős osztály testének vége.
  9. 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.
  10. 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.
  11. Az alaposztályban definiált eat() függvény felülírása. A { a függvénytörzs kezdetét jelöli.
  12. A függvény meghívásakor a konzolra nyomtatandó utasítás.
  13. Az eat() függvény törzsének vége.
  14. Vége az osztály testének Tehén.
  15. Hívja meg a main() függvényt. A { jelöli a függvény törzsének kezdetét.
  16. Hozzon létre egy példányt a Cow osztályból, és adja meg a nevet c.
  17. Hívja meg a Cow osztályban definiált eat() függvényt.
  18. A programnak értéket kell visszaadnia a sikeres befejezés után.
  19. 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:

C++ Virtuális funkció

Itt van egy képernyőkép a kódról:

C++ Virtuális funkció

Kód magyarázata:

  1. Szerelje be az iostream fejlécfájlt a kódba a funkcióinak használatához.
  2. Szerelje be az std névteret a kódunkba, hogy az osztályait hívás nélkül használhassa.
  3. Hozzon létre egy osztályt ClassA néven.
  4. 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.
  5. Hozzon létre egy show() nevű virtuális függvényt. Nyilvános funkció lesz.
  6. 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.
  7. A show() virtuális függvény törzsének vége.
  8. Az A osztály törzsének vége.
  9. Ú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.
  10. 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.
  11. Határozza meg újra az alaposztályból származó show() virtuális függvényt.
  12. A konzolra nyomtatandó szöveg a származtatott osztályban definiált show() függvény meghívásakor.
  13. A show() függvény törzsének vége.
  14. A származtatott osztály törzsének vége, ClassB.
  15. Hívja meg a main() függvényt. A program logikáját hozzá kell adni a törzséhez.
  16. Hozzon létre egy mutatóváltozót a néven. A ClassA nevű osztályra mutat.
  17. Hozzon létre egy példányt az osztályból ClassB néven. A példány neve b.
  18. Rendelje hozzá a tárolt értékeket a b címben az a változóban.
  19. 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.
  20. 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.