Vad är polymorfism i C ++?
I C ++ får polymorfism att en medlemsfunktion beter sig annorlunda baserat på objektet som anropar / åberopar det. Polymorfism är ett grekiskt ord som betyder att ha många former. Det inträffar när du har en hierarki av klasser relaterade genom arv.
Antag till exempel att vi har funktionen makeSound (). När en katt anropar den här funktionen producerar den meow-ljudet. När en ko åberopar samma funktion kommer den att ge moow-ljudet.
Även om vi har en funktion, fungerar den annorlunda under olika omständigheter. Funktionen har många former; därför har vi uppnått polymorfism.
I denna C ++ -handledning lär du dig:
- Vad är polymorfism?
- Typer av polymorfism
- Kompilera tidspolymorfism
- Funktion Överbelastning
- Överbelastning av operatören
- Runtime polymorfism
- Funktion Överstyrning
- C ++ virtuell funktion
- Compile-Time Polymorphism Vs. Runtidspolymorfism
Typer av polymorfism
C ++ stöder två typer av polymorfism:
- Sammanställningstid polymorfism, och
- Runtime polymorfism.
Kompilera tidspolymorfism
Du åberopar de överbelastade funktionerna genom att matcha antalet och typen av argument. Informationen finns under sammanställningstiden. Detta innebär att C ++ - kompilatorn väljer rätt funktion vid kompileringen.
Kompileringstidspolymorfism uppnås genom funktionsöverbelastning och operatörsöverbelastning.
Funktion Överbelastning
Funktionsöverbelastning uppstår när vi har många funktioner med liknande namn men olika argument. Argumenten kan skilja sig åt i antal eller typ.
Exempel 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;}
Produktion:
Här är en skärmdump av koden:
Kodförklaring:
- Inkludera iostream-rubrikfilen i vår kod. Vi kommer att kunna använda dess funktioner.
- Inkludera std-namnområdet i vår kod. Vi kommer att kunna använda sina klasser utan att kalla det.
- Skapa en funktion med namnet test som tar ett heltalsparameter i. {Markerar början på kroppen av funktionstest.
- Uttalande som ska utföras om ovanstående funktionstest åberopas / anropas.
- Slutet på ovanstående funktionstest.
- Skapa en funktion med namnet test som tar en flottörparameter f. {Markerar början på kroppen av funktionstest.
- Uttalande som ska utföras om ovanstående funktionstest åberopas / anropas.
- Slutet på kroppen för ovanstående funktionstest.
- Skapa en funktion med namnet test som tar en teckenparameter ch. {Markerar början på kroppen av funktionstest.
- Uttalande som ska utföras om ovanstående funktionstest åberopas / anropas.
- Slutet på kroppen för ovanstående funktionstest.
- Ring huvudfunktionen (). {Markerar början på kroppens funktion.
- Anropa funktionstestet och skicka 5 till det som argumentets värde. Detta åberopar testfunktionen som accepterar ett heltalargument, det vill säga den första testfunktionen.
- Kalla funktionstestet och skicka 5.5 till det som argumentets värde. Detta kommer att anropa testfunktionen som accepterar ett floatargument, det vill säga den andra testfunktionen.
- Anropa funktionstestet och skicka fem till det som argumentets värde. Detta kommer att anropa testfunktionen som accepterar ett teckenargument, det vill säga den tredje testfunktionen.
- Programmet måste returnera ett värde om det körs framgångsrikt.
- Slutet på huvudfunktionen ().
Vi har tre funktioner med samma namn men olika typer av argument. Vi har uppnått polymorfism.
Överbelastning av operatören
I Operator Overloading definierar vi en ny betydelse för en C ++ - operatör. Det ändrar också hur operatören arbetar. Till exempel kan vi definiera + -operatören för att sammanfoga två strängar. Vi känner det som tilläggsoperatören för att lägga till numeriska värden. Efter vår definition, när den placeras mellan heltal, kommer den att läggas till dem. När den placeras mellan strängarna, sammanfogar den dem.
Exempel 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();}
Produktion:
Här är en skärmdump av koden:
Kodförklaring:
- Inkludera iostream-rubrikfilen i vårt program för att kunna använda dess funktioner.
- Inkludera std-namnområdet i vårt program för att kunna använda sina klasser utan att kalla det.
- Skapa en klass med namnet ComplexNum. {Markerar början på klassens kropp.
- Använd modifieraren för privat åtkomst för att markera variabler som privata, vilket innebär att de endast kan nås från klassen.
- Definiera två heltal variabler, verkliga och över.
- Använd modifieraren för allmän åtkomst för att markera konstruktören som offentlig, vilket innebär att den kommer att vara tillgänglig även utanför klassen.
- Skapa klasskonstruktören och initialisera variablerna.
- Initiera värdet på variabeln real.
- Initiera värdet på variabeln över.
- Slutet på konstruktörskroppen.
- Vi måste åsidosätta innebörden av + -operatören.
- Skapa datatypresultatet av typen ComplexNum.
- Använd + -operatören med komplexa siffror. Denna rad lägger till den verkliga delen av ett nummer till den verkliga delen av ett annat nummer.
- Använd + -operatören med komplexa siffror. Denna rad lägger till den imaginära delen av ett nummer till den imaginära delen av ett annat nummer.
- Programmet returnerar värdet på det variabla resultatet när det genomförts.
- Slutet på definitionen av den nya innebörden av + -operatören, det vill säga överbelastning.
- Ring utskriftsmetoden ().
- Skriv ut det nya komplexa numret efter tillägget på konsolen.
- Slut på funktionen för utskrift ().
- Slutet på kroppen i ComplexNum-klassen.
- Ring huvudfunktionen ().
- Skicka värdena för både verkliga och komplexa delar som ska läggas till. Den första delen av c1 läggs till den första delen av c2, det vill säga 10 + 3. Den andra delen av c1 läggs till den andra delen av c, det vill säga 2 + 7.
- Utför en operation med den överbelastade + -operatören och lagra resultatet i variabel c3.
- Skriv ut värdet på variabeln c3 på konsolen.
- Slutet på huvudfunktionen ().
Runtime polymorfism
Detta händer när ett objekts metod åberopas / anropas under körning snarare än under kompileringstid. Runtime-polymorfism uppnås genom funktionsstyrning. Funktionen som ska anropas / åberopas etableras under körning.
Funktion Överstyrning
Åsidosättande av funktion inträffar när en funktion av basklassen ges en ny definition i en härledd klass. Vid den tiden kan vi säga att basfunktionen har åsidosatts.
Till exempel:
#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;}
Produktion:
Här är en skärmdump av koden:
Kodförklaring:
- Importera iostream-huvudfilen till vårt program för att använda dess funktioner.
- Inkludera std-namnområdet i vårt program för att kunna använda sina klasser utan att kalla det.
- Skapa en klass som heter Mammal. {Markerar början på klassens kropp.
- Använd modifieraren för allmän åtkomst för att ställa in den funktion som vi ska skapa som tillgänglig för allmänheten. Det kommer att vara tillgängligt utanför denna klass.
- Skapa en offentlig funktion som heter eat. {Markerar början på funktionskroppen.
- Skriv ut uttalandet som läggs till cout-funktionen när funktionen eat () åberopas.
- I slutet av kroppens funktion äter ().
- Slutet på kroppen av klassen Däggdjur.
- Skapa en klass med namnet Ko som ärver däggdjursklassen. Ko är den härledda klassen, medan däggdjur är basklassen. {Markerar början på denna klass.
- Använd modifieraren för allmän åtkomst för att markera den funktion som vi ska skapa som allmänt tillgänglig. Det kommer att vara tillgängligt utanför denna klass.
- Åsidosätt funktionen eat () som definierades i basklassen. {Markerar början på funktionskroppen.
- Uttalandet att skriva ut på konsolen när den här funktionen åberopas.
- Slut på kroppen av funktionen äta ().
- Slut på kroppen i klassen Ko.
- Ring huvudfunktionen (). {Markerar början på kroppen för denna funktion.
- Skapa en instans av Cow-klassen och ge den namnet c.
- Ring funktionen eat () definierad i Cow-klassen.
- Programmet måste returnera ett värde när det är klart.
- Slut på huvudfunktionen ().
C ++ virtuell funktion
En virtuell funktion är ett annat sätt att implementera körtidspolymorfism i C ++. Det är en speciell funktion som definieras i en basklass och omdefinieras i den härledda klassen. För att deklarera en virtuell funktion bör du använda det virtuella nyckelordet. Nyckelordet ska föregå funktionens deklaration i basklassen.
Om en klass för virtuell funktion ärvs, omdefinierar den virtuella klassen den virtuella funktionen för att passa dess behov. Till exempel:
#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();}
Produktion:
Här är en skärmdump av koden:
Kodförklaring:
- Inkludera iostream-rubrikfilen i koden för att använda dess funktioner.
- Inkludera std-namnområdet i vår kod för att använda sina klasser utan att kalla det.
- Skapa en klass som heter ClassA.
- Använd modifieraren för allmän tillgång för att markera en klassmedlem som allmänt tillgänglig.
- Skapa en virtuell funktion med namnet show (). Det kommer att vara en offentlig funktion.
- Texten som ska skrivas ut när showen () åberopas åberopas. Endl är ett C ++ nyckelord, vilket betyder slutrad. Den flyttar muspekaren till nästa rad.
- Slutet på kroppen för den virtuella funktionsprogrammet ().
- Slut på kroppen i klass ClassA.
- Skapa en ny klass med namnet ClassB som ärver klassen ClassA. KlassA blir basklassen medan klassB blir den härledda klassen.
- Använd modifieraren för allmän tillgång för att markera en klassmedlem som allmänt tillgänglig.
- Definiera om det virtuella funktionsprogrammet () som härrör från basklassen.
- Texten som ska skrivas ut på konsolen när funktionen show () som definieras i den härledda klassen åberopas.
- Slutet på showen () -funktionens huvuddel.
- Slutet på kroppen i den härledda klassen, klass B.
- Ring huvudfunktionen (). Programmets logik bör läggas till i sin kropp.
- Skapa en pekervariabel med namnet a. Det pekar på klassen som heter ClassA.
- Skapa en instans av klassen som heter ClassB. Instansen får namnet b.
- Tilldela värden lagras i adressen b i variabeln a.
- Anropa funktionen show () definierad i den härledda klassen. Sen bindning har genomförts.
- Slutet på huvudfunktionens () kropp.
Compile-Time Polymorphism Vs. Runtidspolymorfism
Här är de stora skillnaderna mellan de två:
Sammanställningstidspolymorfism | Körtidspolymorfism |
Det kallas också tidig bindning eller statisk polymorfism | Det kallas också sen / dynamisk bindning eller dynamisk polymorfism |
Metoden kallas / åberopas under kompileringstiden | Metoden kallas / åberopas under körningstiden |
Implementeras via funktionsöverbelastning och operatörsöverbelastning | Implementeras via metodöverstyrning och virtuella funktioner |
Exempel på metodöverbelastning. Många metoder kan ha liknande namn men olika antal eller typer av argument | Exempel, metod som åsidosätter. Många metoder kan ha ett liknande namn och samma prototyp. |
Snabbare körning eftersom metodupptäckten görs under kompileringstiden | Långsammare körning eftersom metodupptäckaren görs under körning. |
Mindre flexibilitet för problemlösning tillhandahålls eftersom allt är känt under kompileringstiden. | Mycket flexibilitet ges för att lösa komplexa problem eftersom metoder upptäcks under körning. |
Sammanfattning:
- Polymorfism betyder att ha många former.
- Det inträffar när det finns en hierarki av klasser relaterade genom arv.
- Med polymorfism kan en funktion bete sig annorlunda baserat på objektet som åberopar / kallar det.
- Vid polymorfism med kompileringstid fastställs den funktion som ska åberopas under kompileringstid.
- Vid körningspolymorfism etableras den funktion som ska åberopas under körning.
- Sammanställningstidspolymorfism bestäms genom funktionsöverbelastning och operatörsöverbelastning.
- I funktionsöverbelastning finns det många funktioner med liknande namn men olika argument.
- Parametrarna kan variera i antal eller typ.
- Vid överbelastning av operatörer definieras en ny mening för C ++ -operatörer.
- Runtime-polymorfism uppnås genom funktionsstyrning.
- Vid funktionsöverstyrning ger en härledd klass en ny definition till en funktion som definieras i basklassen.