polymorphism c
Úloha polymorfizmu v C ++ s príkladmi.
Polymorfizmus je jedným zo štyroch pilierov objektovo orientovaného programovania. Polymorfizmus znamená mať veľa podôb. Dá sa to definovať ako technika, ktorou môže mať objekt rôzne situácie v závislosti od situácie.
Z programového hľadiska môžeme povedať, že objekt sa môže v rôznych podmienkach správať odlišne.
V tomto tutoriáli sa dozvieme podrobnejšie typy polymorfizmu, spôsoby implementácie polymorfizmu spolu s rôznymi inými konceptmi polymorfizmu.
=> Ak chcete vidieť A-Z výučbových kurzov C ++, kliknite sem.
Napríklad, žena môže zaujať veľa rolí v rôznych situáciách. Pre dieťa je to matka, domáca žena v domácnosti, pracovníčka v kancelárii atď. Žena teda preberá rôzne roly a prejavuje sa odlišným správaním v rôznych podmienkach. Toto je skutočný príklad polymorfizmu.
Podobne vo svete programovania môžeme mať aj operátor „+“, čo je operátor binárneho sčítania, ktorý sa pri zmene operandov správa inak. Napríklad, keď sú oba operandy číselné, vykoná sčítanie.
Na druhej strane, keď sú operandy reťazcové, funguje ako zreťazovací operátor. Polymorfizmus teda v skratke znamená entitu, ktorá má rôzne formy alebo sa správa za rôznych podmienok odlišne.
Čo sa dozviete:
- Typy polymorfizmu
- Kompilovať časový polymorfizmus vs. Polymorfizmus za behu
- Zostavte časový polymorfizmus
- Funkčné preťaženie
- Preťaženie operátora
- Záver
- Odporúčané čítanie
Typy polymorfizmu
Polymorfizmus je rozdelený do dvoch typov.
- Zostavte časový polymorfizmus
- Polymorfizmus za behu
Diagram, ktorý to predstavuje, je uvedený nižšie:
Ako je zrejmé z vyššie uvedeného diagramu, polymorfizmus je rozdelený na polymorfizmus v čase kompilácie a runtime polymorfizmus. Polymorfizmus času kompilácie sa ďalej delí na preťaženie operátora a preťaženie funkcie. Runtime polymorfizmus sa ďalej implementuje pomocou virtuálnych funkcií.
Polymorfizmus času kompilácie je tiež známy ako skorý väzbový alebo statický polymorfizmus. U tohto typu polymorfizmu sa metóda objektu vyvoláva v čase kompilácie. V prípade runtime polymorfizmu sa metóda objektu vyvolá za behu programu.
Runtime polymorfizmus je tiež známy ako dynamický alebo neskorý väzbový proces alebo dynamický polymorfizmus. Podrobnej implementácii každej z týchto techník sa budeme venovať v nasledujúcich témach.
Kompilovať časový polymorfizmus vs. Polymorfizmus za behu
Pozrime sa na hlavné rozdiely medzi časom kompilácie a runtime polymorfizmom.
Zostavte časový polymorfizmus | Polymorfizmus za behu |
---|---|
Známy tiež ako statický polymorfizmus alebo skorá väzba | Známy tiež ako dynamický polymorfizmus alebo neskoré / dynamické viazanie |
Metóda Objects je vyvolaná v čase kompilácie | Metóda objektu je vyvolaná za behu programu |
Zvyčajne sa implementuje pomocou preťaženia operátora a preťaženia funkcie | Implementované pomocou virtuálnych funkcií a prepísania metódy |
Preťaženie metódy je polymorfizmus kompilácie, v ktorom môže mať viac ako jedna metóda rovnaký názov, ale odlišný zoznam a typy parametrov. | Prepísanie metódy je runtime polymorfizmus, pri ktorom má viac ako jedna metóda rovnaký názov s rovnakým prototypom |
Pretože metódy sú známe v čase kompilácie, vykonávanie je rýchlejšie | Vykonávanie je pomalšie, pretože metóda je známa za behu programu |
Poskytujte menšiu flexibilitu pri implementácii riešení, pretože všetko treba vedieť v čase kompilácie | Oveľa flexibilnejšia pri implementácii komplexných riešení, pretože metódy sa rozhodujú za behu |
Zostavte časový polymorfizmus
Polymorfizmus v čase kompilácie je technika, pri ktorej sa v čase kompilácie vyvolá metóda objektu.
Tento typ polymorfizmu je implementovaný dvoma spôsobmi.
- Preťaženie funkcií
- Preťaženie obsluhy
Budeme podrobne diskutovať o každej technike.
Funkčné preťaženie
Hovorí sa, že funkcia je preťažená, keď máme viac ako jednu funkciu s rovnakým názvom, ale rôznymi typmi parametrov alebo rôznym počtom argumentov.
Funkciu je teda možné preťažiť na základe typov parametrov, poradia parametrov a počtu parametrov.
Pamätajte, že dve funkcie, ktoré majú rovnaký názov a rovnaký zoznam parametrov, ale odlišný návratový typ, nie sú preťaženou funkciou a pri použití v programe budú mať za následok chybu kompilácie.
Podobne, keď sa parametre funkcie líšia iba ukazovateľom a ak je typ poľa ekvivalentný, potom by sa nemal používať na preťaženie.
Ostatné typy ako statické a nestatické, konštantné a volatilné atď. Alebo deklarácie parametrov, ktoré sa líšia v prítomnosti alebo neprítomnosti predvolených hodnôt, sa tiež nepoužívajú na preťaženie, pretože sú z hľadiska implementácie rovnocenné.
Napríklad,nasledujúce funkčné prototypy sú preťažené funkcie.
Add(int,int); Add(int,float); Add(float,int); Add(int,int,int);
Na vyššie uvedených prototypoch vidíme, že funkciu Add preťažujeme na základe typu parametrov, postupnosti alebo poradia parametrov, počtu parametrov atď.
Zoberme si kompletný programovací príklad, aby sme lepšie pochopili preťaženie funkcií.
#include #include using namespace std; class Summation { public: int Add(int num1,int num2) { return num1+num2; } int Add(int num1,int num2, int num3) { return num1+num2+num3; } string Add(string s1,string s2){ return s1+s2; } }; int main(void) { Summation obj; cout< Výkon:
35
191
19
Ahoj svet
Vo vyššie uvedenom programe máme triedu Summation, ktorá definovala tri preťažené funkcie s názvom Add, ktorá prijíma dva celočíselné argumenty, tri celočíselné argumenty a dva reťazcové argumenty.
V hlavnej funkcii uskutočňujeme štyri volania funkcií, ktoré poskytujú rôzne parametre. Prvé dve volania funkcií sú priame. V rámci tretieho volania funkcie Add poskytujeme dve hodnoty s pohyblivou rádovou čiarkou ako argumenty.
V tomto prípade je funkcia, ktorá je priradená, int Add (int, int) ako interne, float sa prevedie na dvojnásobok a potom sa porovná s funkciou s parametrami int. Keby sme zadali double namiesto float, potom by sme mali ďalšiu preťaženú funkciu s double ako parametrami.
Posledné volanie funkcie používa ako parametre reťazcové hodnoty. V takom prípade operátor Add (+) funguje ako operátor zreťazenia a zreťazuje dve hodnoty reťazca tak, aby vytvoril jeden reťazec.
Výhody preťaženia funkcií
Hlavnou výhodou preťaženia funkcií je to, že podporuje opätovné použitie kódu. Môžeme mať čo najviac funkcií s rovnakým názvom, pokiaľ sú preťažené na základe typu argumentu, postupnosti argumentov a počtu argumentov.
Týmto spôsobom je jednoduchšie mať rôzne funkcie s rovnakým názvom, ktoré reprezentujú chovanie tej istej operácie v rôznych podmienkach.
Keby nebolo preťaženie funkcií, potom by sme museli napísať príliš veľa rôznych druhov funkcií s rôznymi názvami, čím by sa kód stal nečitateľným a ťažko sa prispôsobil.
Preťaženie operátora
Preťaženie operátorov je technika, pomocou ktorej dáme existujúcim operátorom v C ++ iný význam. Inými slovami, preťažujeme operátory, aby používateľom definované dátové typy dávali osobitný význam ako objekty.
Väčšina operátorov v C ++ je preťažená alebo im má špeciálny význam, aby mohli pracovať na používateľom definovaných dátových typoch. Upozorňujeme, že počas preťaženia sa základná operácia operátorov nezmení. Preťaženie dáva operátorovi ďalší význam tým, že zachováva jeho základnú sémantiku rovnako.
Aj keď väčšinu operátorov je možné v C ++ preťažiť, existuje niekoľko operátorov, ktoré sa nedajú preťažiť.
Tieto operátory sú uvedené v nasledujúcej tabuľke.
Operátorov Operátor riešenia rozsahu (: :) Veľkosť selektor členov (.) selektor ukazovateľa člena (*) ternárny operátor (? :)
Funkcie, ktoré používame na preťaženie operátorov, sa nazývajú „ Funkcie operátora “.
Funkcie operátora sú podobné normálnym funkciám, ale s rozdielom. Rozdiel je v tom, že názov funkcií operátora sa začína kľúčovým slovom „ operátor ”Nasledovaný symbolom operátora, ktorý má byť preťažený.
Potom sa zavolá funkcia operátora, keď sa v programe použije príslušný operátor. Tieto operátorské funkcie môžu byť členské funkcie alebo globálne metódy alebo dokonca priateľská funkcia.
Všeobecná syntax funkcie operátora je:
return_type classname::operator op(parameter list) { //function body }
„Operátor op“ je tu funkcia operátora, kde operátor je kľúčové slovo a op je operátor, ktorý sa má preťažiť. Return_type je typ hodnoty, ktorý sa má vrátiť.
Pozrime sa na niekoľko príkladov programovania, ktoré demonštrujú preťaženie operátora pomocou funkcií operátora.
Príklad 1:Preťaženie unárneho operátora pomocou funkcie člena operátora.
#include using namespace std; class Distance { public: int feet; // Constructor to initialize the object's value Distance(int feet) { this->feet = feet; } //operator function to overload ++ operator to perform increment on Distance obj void operator++() { feet++; } void print(){ cout << '
Incremented Feet value: ' << feet; } }; int main() { Distance d1(9); // Use (++) unary operator ++d1; d1.print(); return 0; }
Výkon:
Hodnota zvýšených stôp: 10
Tu sme preťažili unárny prírastkový operátor pomocou funkcie operator ++. V hlavnej funkcii používame tento operátor ++ na zvýšenie objektu triedy Distance.
Príklad 2:Preťaženie binárneho operátora pomocou funkcie člena operátora.
#include using namespace std; class Complex { int real, imag; public: Complex(int r = 0, int i =0) {real = r; imag = i;} //Operator function to overload binary + to add two complex numbers Complex operator + (Complex const &obj) { Complex c3; c3.real = real + obj.real; c3.imag = imag + obj.imag; return c3; } void print() { cout << real << ' + i' << imag << endl; } }; int main() { Complex c1(2, 5), c2(3, 7); cout<<'c1 = '; c1.print(); cout<<'c2 = '; c2.print(); cout<<'c3 = c1+c2 = '; Complex c3 = c1 + c2; // calls overloaded + operator c3.print(); }
Výkon:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Tu sme použili klasický príklad sčítania dvoch komplexných čísel pomocou preťaženia operátora. Definujeme triedu, ktorá predstavuje komplexné čísla, a operátorskú funkciu preťaženia + operátor, do ktorej sčítame reálnu a imaginárnu časť komplexných čísel.
V hlavnej funkcii deklarujeme dva zložité objekty a pomocou operátora preťaženia + ich pridáme, aby sme dosiahli požadovaný výsledok.
V nasledujúcom príklade použijeme funkciu friend na pridanie dvoch komplexných čísel, aby sme videli rozdiel v implementácii.
#include using namespace std; class Complex { int real, imag; public: Complex(int r = 0, int i =0) {real = r; imag = i;} //friend function to overload binary + to add two complex numbers friend Complex operator +(Complex const &, Complex const &); void print() { cout << real << ' + i' << imag << endl; } }; Complex operator + (Complex const &c1, Complex const &c2) { Complex c3; c3.real = c1.real + c2.real; c3.imag = c1.imag + c2.imag; return c3; } int main() { Complex c1(2, 5), c2(3, 7); cout<<'c1 = '; c1.print(); cout<<'c2 = '; c2.print(); cout<<'c3 = c1+c2 = '; Complex c3 = c1 + c2; // calls overloaded + operator c3.print(); }
Výkon:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Vidíme, že výstup programu je rovnaký. Jediným rozdielom v implementácii je použitie funkcie friend na preťaženie operátora + namiesto členskej funkcie v predchádzajúcej implementácii.
Keď sa priateľská funkcia používa pre binárny operátor, musíme tejto funkcii explicitne určiť obidva operandy. Podobne, keď je unárny operátor preťažený pomocou funkcie priateľa, musíme funkcii poskytnúť jediný operand.
Okrem funkcií operátora môžeme napísať aj a operátor konverzie ktorá sa používa na prevod z jedného typu na druhý. Tieto preťažené operátory prevodu by mali byť členskou funkciou triedy.
Príklad 3:Preťaženie operátora pomocou operátora konverzie.
#include using namespace std; class DecFraction { int numerator, denom; public: DecFraction(int num, int denm) { numerator = num; denom = denm; } // conversion operator: converts fraction to float value and returns it operator float() const { return float(numerator) / float(denom); } }; int main() { DecFraction df(3, 5); //object of class float res_val = df; //calls conversion operator cout << 'The resultant value of given fraction (3,5)= '< Výkon:
Výsledná hodnota daného zlomku (3,5) = 0,6
V tomto programe sme použili operátor prepočtu na prevod danej frakcie na floatovanú hodnotu. Po dokončení prevodu vráti operátor konverzie výslednú hodnotu volajúcemu.
V hlavnej funkcii, keď priradíme objekt df k premennej res_val, dôjde k prepočtu a výsledok sa uloží do res_val.
Konštruktor môžeme nazvať aj jediným argumentom. Keď môžeme zavolať konštruktor z triedy pomocou jediného argumentu, nazýva sa to „ premena staviteľ “. Konštruktor konverzie je možné použiť na implicitný prevod na triedu, ktorá sa vytvára.
#include using namespace std; class Point { private: int x,y; public: Point(int i=0,int j=0) {x = i;y=j;} void print() { cout<<' x = '< Výkon:
Bod zostrojený pomocou normálneho konštruktora
x = 20 y = 30
Bod zostrojený pomocou konštruktéra konverzie
x = 10 y = 0
ako pridať prvky do poľa v jave -
Tu máme triedu Point, ktorá definuje konštruktor s predvolenými hodnotami. V hlavnej funkcii zostrojíme objekt pt so súradnicami xay. Ďalej len priradíme pt hodnotu 10. Toto je miesto, kde sa volá konštruktor konverzie a x je priradená hodnota 10, zatiaľ čo y má predvolenú hodnotu 0.
Pravidlá preťaženia operátora
Pri preťažovaní operátora si musíme dávať pozor na nasledujúce pravidlá.
- V C ++ sme schopní preťažiť iba existujúcich operátorov. Novo pridané operátory nemôžu byť preťažené.
- Keď sú operátory preťažené, musíme zabezpečiť, aby aspoň jeden z operandov bol používateľom definovaného typu.
- Na preťaženie určitých operátorov môžeme tiež využiť funkciu priateľa.
- Keď preťažíme unárne operátory pomocou členskej funkcie, nebude to vyžadovať explicitné argumenty. Trvá jeden explicitný argument, keď je unárny operátor preťažený pomocou funkcie friend.
- Podobne, keď sú binárne operátory preťažené pomocou členskej funkcie, musíme funkcii poskytnúť jeden explicitný argument. Keď sú binárne operátory preťažené pomocou funkcie friend, funkcia má dva argumenty.
- V C ++ sú dvaja operátori, ktorí sú už preťažení. Toto sú „=“ a „&“. Preto, aby sme skopírovali objekt rovnakej triedy, nemusíme preťažovať operátor = a môžeme ho použiť priamo.
Výhody preťaženia operátora
Preťaženie operátora v C ++ nám umožňuje okrem zabudovaných typov rozšíriť funkčnosť operátorov na typy definované používateľom vrátane objektov triedy.
Rozšírením funkčnosti operátora na typy definované používateľom nemusíme písať zložitý kód na vykonávanie rôznych operácií na typoch definovaných používateľom, ale môžeme to urobiť jednou operáciou samotnou, rovnako ako vstavané typy.
Záver
Polymorfizmus času kompilácie poskytuje funkciu preťaženia hlavne na rozšírenie funkčnosti kódu z hľadiska preťaženia funkcií a preťaženia operátora.
Vďaka preťaženiu funkcií môžeme napísať viac ako jednu funkciu s rovnakým názvom, ale rôznymi parametrami a typmi. Vďaka tomu je kód jednoduchý a ľahko čitateľný. Preťažením operátora môžeme rozšíriť funkčnosť operátorov, aby sme mohli vykonávať základné operácie aj na používateľom definovaných typoch.
V našom pripravovanom výučbe sa dozvieme viac o runtime polymorfizme v C ++.
=> Prečítajte si sériu Easy C ++ Training Series.
Odporúčané čítanie
- Runtime polymorfizmus v C ++
- Funkcie priateľov v C ++
- Rekurzia v C ++
- Výukový program pre hlavné funkcie Pythonu s praktickými príkladmi
- Kompletný prehľad jazyka C ++
- Výukový program QTP # 21 - Ako vytvoriť modulárne a opakovane použiteľné testy QTP pomocou knižníc akcií a funkcií
- Výukový program pre Unix Pipes: Rúry v programovaní v Unixe
- Funkcie knižnice v C ++