Čo je to polymorfizmus v C ++?
V C ++ spôsobuje polymorfizmus to, že sa členská funkcia správa odlišne na základe objektu, ktorý ju volá / vyvoláva. Polymorfizmus je grécke slovo, ktoré znamená mať veľa podôb. Nastáva, keď máte hierarchiu tried príbuzných prostredníctvom dedenia.
Predpokladajme napríklad, že máme funkciu makeSound (). Keď mačka volá túto funkciu, vyprodukuje mňaukavý zvuk. Keď krava vyvolá rovnakú funkciu, poskytne zvuk móla.
Aj keď máme jednu funkciu, správa sa za rôznych okolností odlišne. Funkcia má veľa podôb; teda sme dosiahli polymorfizmus.
V tomto výučbe pre C ++ sa dozviete:
- Čo je to polymorfizmus?
- Typy polymorfizmu
- Zostavte časový polymorfizmus
- Funkčné preťaženie
- Preťaženie operátora
- Runtime polymorfizmus
- Prepísanie funkcie
- C ++ virtuálna funkcia
- Polymorfizmus v čase kompilácie vs. Polymorfizmus za behu
Typy polymorfizmu
Jazyk C ++ podporuje dva typy polymorfizmu:
- Polymorfizmus v čase kompilácie a
- Polymorfizmus za behu.
Zostavte časový polymorfizmus
Preťažené funkcie vyvoláte zhodou počtu a typu argumentov. Informácie sú k dispozícii počas kompilácie. To znamená, že kompilátor C ++ vyberie správnu funkciu v čase kompilácie.
Polymorfizmus v kompilácii sa dosahuje preťažením funkcií a preťažením operátora.
Funkčné preťaženie
K preťaženiu funkcií dôjde, keď máme veľa funkcií s podobnými názvami, ale rôznymi argumentmi. Argumenty sa môžu líšiť, pokiaľ ide o počet alebo typ.
Príklad 1:
#includeusing 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;}
Výkon:
Tu je snímka obrazovky s kódom:
Vysvetlenie kódu:
- Zahrňte súbor hlavičky iostream do nášho kódu. Budeme môcť využívať jeho funkcie.
- Zahrňte do nášho kódu štandardný menný priestor. Budeme môcť používať jeho triedy bez toho, aby sme ich volali.
- Vytvorte funkciu s názvom test, ktorá vezme celočíselný parameter i. {Označuje začiatok testu funkčnej funkcie.
- Príkaz, ktorý sa má vykonať, ak sa vyvolá / volá vyššie uvedený funkčný test.
- Koniec tela funkčnej skúšky uvedenej vyššie.
- Vytvorte funkciu s názvom test, ktorá prevezme plavákový parameter f. {Označuje začiatok testu funkčnej funkcie.
- Príkaz, ktorý sa má vykonať, ak sa vyvolá / volá vyššie uvedený funkčný test.
- Koniec tela vyššie uvedenej funkčnej skúšky.
- Vytvorte funkciu s názvom test, ktorá bude mať znakový parameter ch. {Označuje začiatok testu funkčnej funkcie.
- Príkaz, ktorý sa má vykonať, ak sa vyvolá / volá vyššie uvedený funkčný test.
- Koniec tela vyššie uvedenej funkčnej skúšky.
- Zavolajte funkciu main (). {Označuje začiatok tela funkcie.
- Zavolajte test funkcie a odovzdajte mu 5 ako hodnotu argumentu. Toto vyvolá testovaciu funkciu, ktorá akceptuje celočíselný argument, to znamená prvú testovaciu funkciu.
- Zavolajte test funkcie a odovzdajte mu 5,5 ako hodnotu argumentu. To vyvolá testovaciu funkciu, ktorá akceptuje floatový argument, to znamená druhú testovaciu funkciu.
- Zavolajte test funkcie a odovzdajte päť ako hodnotu argumentu. To vyvolá testovaciu funkciu, ktorá akceptuje znakový argument, teda tretiu testovaciu funkciu.
- Ak program beží úspešne, musí vrátiť hodnotu.
- Koniec tela hlavnej () funkcie.
Máme tri funkcie s rovnakým názvom, ale s rôznymi typmi argumentov. Dosiahli sme polymorfizmus.
Preťaženie operátora
V operátorskom preťažení definujeme nový význam pre operátor C ++. Mení tiež spôsob fungovania operátora. Napríklad môžeme definovať operátor + na zreťazenie dvoch reťazcov. Poznáme ho ako operátor sčítania pre pridávanie číselných hodnôt. Podľa našej definície, keď sa umiestni medzi celé čísla, pridá ich. Ak sa umiestni medzi struny, spojí ich to.
Príklad 2:
#includeusing 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();}
Výkon:
Tu je snímka obrazovky s kódom:
Vysvetlenie kódu:
- Zahrňte súbor hlavičky iostream do nášho programu, aby ste mohli využívať jeho funkcie.
- Zahrňte do nášho programu std namespace, aby ste mohli používať jeho triedy bez toho, aby ste ich volali.
- Vytvorte triedu s názvom ComplexNum. {Označuje začiatok tela triedy.
- Použite modifikátor súkromného prístupu na označenie premenných ako súkromných, čo znamená, že k nim je možné získať prístup iba z triedy.
- Definujte dve celočíselné premenné, skutočnú a ďalšiu.
- Použite modifikátor verejného prístupu na označenie konštruktora ako verejného, čo znamená, že bude prístupný aj mimo triedy.
- Vytvorte konštruktor triedy a inicializujte premenné.
- Inicializujte hodnotu premennej real.
- Inicializujte hodnotu premennej znova.
- Koniec tela konštruktéra.
- Musíme prepísať význam operátora +.
- Vytvorte výsledok dátového typu typu ComplexNum.
- Použite operátor + s komplexnými číslami. Tento riadok pridá skutočnú časť čísla k skutočnej časti iného čísla.
- Použite operátor + s komplexnými číslami. Tento riadok pridá imaginárnu časť čísla k imaginárnej časti iného čísla.
- Po úspešnom vykonaní program vráti hodnotu výsledku premennej.
- Koniec definície nového významu operátora +, teda preťaženia.
- Zavolajte metódu print ().
- Po pridaní na konzolu vytlačte nové komplexné číslo.
- Koniec tela funkcie print ().
- Koniec tela triedy ComplexNum.
- Zavolajte funkciu main ().
- Odovzdajte hodnoty skutočných aj zložitých častí, ktoré sa majú pridať. Prvá časť C1 sa pridá k prvej časti C2, teda 10 + 3. Druhá časť C1 sa pridá k druhej časti C, teda 2 + 7.
- Vykonajte operáciu pomocou operátora preťaženého + a výsledok uložte do premennej c3.
- Vytlačte hodnotu premennej c3 na konzolu.
- Koniec tela hlavnej () funkcie.
Runtime polymorfizmus
To sa stane, keď je metóda objektu vyvolaná / volaná počas behu programu, a nie počas kompilácie. Runtime polymorfizmus sa dosahuje prepísaním funkcií. Funkcia, ktorá sa má volať / vyvolať, sa vytvorí počas behu programu.
Prepísanie funkcie
K prepísaniu funkcie dôjde, keď funkcia základnej triedy dostane novú definíciu v odvodenej triede. V tom čase môžeme povedať, že bola prepísaná základná funkcia.
Napríklad:
#includeusing 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;}
Výkon:
Tu je snímka obrazovky s kódom:
Vysvetlenie kódu:
- Importujte súbor hlavičky iostream do nášho programu, aby ste mohli využívať jeho funkcie.
- Zahrňte do nášho programu std namespace, aby ste mohli používať jeho triedy bez toho, aby ste ich volali.
- Vytvorte triedu s názvom Cicavec. {Označuje začiatok tela triedy.
- Pomocou modifikátora verejného prístupu nastavte funkciu, ktorú sa chystáme vytvoriť, ako verejne prístupnú. Bude prístupné mimo tejto triedy.
- Vytvorte verejnú funkciu s názvom jesť. {Označuje začiatok tela funkcie.
- Vytlačí vyhlásenie pridané k funkcii cout, keď je vyvolaná funkcia eat ().
- Koniec tela funkcie jesť ().
- Koniec tela triedy Cicavec.
- Vytvorte triedu s názvom Krava, ktorá zdedí triedu Cicavce. Krava je odvodená trieda, zatiaľ čo cicavec je základná trieda. {Označuje začiatok tejto triedy.
- Pomocou modifikátora verejného prístupu označte funkciu, ktorú sa chystáme vytvoriť, ako verejne prístupnú. Bude prístupné mimo tejto triedy.
- Prepíše funkciu eat (), ktorá bola definovaná v základnej triede. {Označuje začiatok tela funkcie.
- Príkaz, ktorý sa má vytlačiť na konzole, keď je vyvolaná táto funkcia.
- Koniec tela funkcie jesť ().
- Koniec tela triedy Krava.
- Zavolajte funkciu main (). {Označuje začiatok tela tejto funkcie.
- Vytvorte inštanciu triedy Cow a pomenujte ju c.
- Zavolajte funkciu eat () definovanú v triede Krava.
- Po úspešnom dokončení musí program vrátiť hodnotu.
- Koniec hlavnej funkcie ().
C ++ virtuálna funkcia
Virtuálna funkcia je ďalším spôsobom implementácie run-time polymorfizmu v C ++. Je to špeciálna funkcia definovaná v základnej triede a predefinovaná v odvodenej triede. Ak chcete deklarovať virtuálnu funkciu, mali by ste použiť virtuálne kľúčové slovo. Kľúčové slovo by malo predchádzať deklarácii funkcie v základnej triede.
Ak sa trieda virtuálnych funkcií dedí, virtuálna trieda predefinuje virtuálnu funkciu tak, aby vyhovovala jej potrebám. Napríklad:
#includeusing 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();}
Výkon:
Tu je snímka obrazovky s kódom:
Vysvetlenie kódu:
- Zahrňte do kódu súbor hlavičky iostream, aby ste mohli využívať jeho funkcie.
- Ak chcete používať svoje triedy bez toho, aby ste ich volali, zahrňte do nášho kódu std namespace.
- Vytvorte triedu s názvom ClassA.
- Použite modifikátor verejného prístupu na označenie člena triedy ako verejne prístupného.
- Vytvorte virtuálnu funkciu s názvom show (). Bude to verejná funkcia.
- Text, ktorý sa má vytlačiť, keď sa vyvolá show (). Endl je kľúčové slovo C ++, čo znamená koncový riadok. Presunie kurzor myši na ďalší riadok.
- Koniec tela virtuálnej funkčnej show ().
- Koniec tela triedy ClassA.
- Vytvorenie novej triedy s názvom ClassB, ktorá dedí triedu ClassA. ClassA sa stáva základnou triedou, zatiaľ čo ClassB sa stáva odvodenou triedou.
- Použite modifikátor verejného prístupu na označenie člena triedy ako verejne prístupného.
- Predefinujte virtuálnu funkciu show () odvodenú v základnej triede.
- Text, ktorý sa má vytlačiť na konzolu, keď sa vyvolá funkcia show () definovaná v odvodenej triede.
- Koniec tela funkcie show ().
- Koniec tela odvodenej triedy, ClassB.
- Zavolajte funkciu main (). Logika programu by mala byť pridaná do jeho tela.
- Vytvorte premennú ukazovateľa s názvom a. Ukazuje na triedu s názvom ClassA.
- Vytvorte inštanciu triedy s názvom ClassB. Inštitúcia má názov b.
- Priraďte ukladané hodnoty k adrese b v premennej a.
- Vyvolajte funkciu show () definovanú v odvodenej triede. Bola implementovaná neskorá väzba.
- Koniec tela hlavnej () funkcie.
Polymorfizmus v čase kompilácie vs. Polymorfizmus za behu
Tu sú hlavné rozdiely medzi nimi:
Polymorfizmus v čase kompilácie | Polymorfizmus za behu |
Nazýva sa to tiež predčasná väzba alebo statický polymorfizmus | Nazýva sa to tiež neskorá / dynamická väzba alebo dynamický polymorfizmus |
Metóda sa volá / vyvolá počas kompilácie | Metóda sa volá / vyvolá počas behu |
Implementované prostredníctvom preťaženia funkcií a preťaženia operátora | Implementované prostredníctvom prepísania metódy a virtuálnych funkcií |
Príklad preťaženia metódy. Mnoho metód môže mať podobné názvy, ale rôzny počet alebo typy argumentov | Príklad prepísania metódy. Mnoho metód môže mať podobný názov a rovnaký prototyp. |
Rýchlejšie vykonávanie, pretože zisťovanie metód sa vykonáva počas kompilácie | Pomalšie vykonávanie, pretože vyhľadávač metód sa vykonáva počas behu programu. |
Poskytuje sa menšia flexibilita pri riešení problémov, pretože všetko je známe počas kompilácie. | Na riešenie zložitých problémov je poskytnutá veľká flexibilita, pretože metódy sa objavujú počas behu programu. |
Zhrnutie:
- Polymorfizmus znamená mať veľa podôb.
- Nastáva, keď existuje hierarchia tried súvisiacich prostredníctvom dedenia.
- Pri polymorfizme sa funkcia môže správať odlišne na základe objektu, ktorý ju vyvoláva / volá.
- V polymorfizme kompilácie sa funkcia, ktorá sa má vyvolať, ustanoví počas kompilácie.
- V polymorfizme za behu sa funkcia, ktorá sa má vyvolať, ustanovuje za behu modulu.
- Polymorfizmus v čase kompilácie je určený preťažením funkcií a preťažením operátora.
- Pri preťažení funkcií existuje veľa funkcií s podobnými názvami, ale s rôznymi argumentmi.
- Parametre sa môžu líšiť počtom alebo typom.
- Pri preťažovaní operátorov je pre operátorov C ++ definovaný nový význam.
- Runtime polymorfizmus sa dosahuje prepísaním funkcií.
- Pri prepísaní funkcií odvodená trieda dáva novú definíciu funkcii definovanej v základnej triede.