polymorphism c
Polymorfismens roll i C ++ med exempel.
Polymorfism är en av de fyra pelarna i objektorienterad programmering. Polymorfism betyder att ha många former. Det kan definieras som den teknik genom vilken ett objekt kan ta många former beroende på situationen.
I programmeringsmässiga termer kan vi säga att ett objekt kan bete sig annorlunda under olika förhållanden.
I denna handledning lär vi oss om typerna av polymorfism, sätten att implementera polymorfism tillsammans med de olika andra begreppen polymorfism i detalj.
=> Kolla här för att se A-Z av C ++ träningstutorialer här.
Till exempel, en kvinna kan ta många roller i olika situationer. För ett barn är hon mamma, hemma hemma, arbetare på kontoret osv. Så en kvinna tar olika roller och uppvisar olika beteende under olika förhållanden. Detta är ett verkligt exempel på polymorfism.
På samma sätt i programmeringsvärlden kan vi också ha en operatör '+' som är den binära additionsoperatören som beter sig annorlunda när operanderna ändras. Till exempel, när båda operanderna är numeriska utför den addition.
Å andra sidan, när operanderna är strängar, fungerar den som sammanlänkningsoperator. Således betyder polymorfism, i ett nötskal, en enhet som tar upp många former eller beter sig annorlunda under olika förhållanden.
Vad du kommer att lära dig:
- Typer av polymorfism
- Kompilera tidspolymorfism vs. Runtidspolymorfism
- Kompilera tidspolymorfism
- Funktion överbelastning
- Överbelastning av operatören
- Slutsats
- Rekommenderad läsning
Typer av polymorfism
Polymorfism är uppdelad i två typer.
- Kompilera tidspolymorfism
- Runtime polymorfism
Diagrammet för att representera detta visas nedan:
Som visas i ovanstående diagram är polymorfism uppdelad i polymorfism med sammanställningstid och polymorfism under körning. Kompileringstidspolymorfism delas vidare in i operatörsöverbelastning och funktionsöverbelastning. Runtime polymorfism implementeras vidare med virtuella funktioner.
Sammanställningstidspolymorfism är också känd som tidig bindning eller statisk polymorfism. I denna typ av polymorfism åberopas objektets metod vid sammanställningstiden. Vid körningspolymorfism åberopas objektets metod vid körningstid.
Runtime-polymorfism är också känd som dynamisk eller sen bindning eller dynamisk polymorfism. Vi kommer att undersöka den detaljerade implementeringen av var och en av dessa tekniker i våra följande ämnen.
Kompilera tidspolymorfism vs. Runtidspolymorfism
Låt oss se de viktigaste skillnaderna mellan kompileringstid och runtime polymorfism nedan.
Kompilera tidspolymorfism | Runtime polymorfism |
---|---|
Även känd som statisk polymorfism eller tidig bindning | Även känd som dynamisk polymorfism eller sen / dynamisk bindning |
Objektmetoden åberopas vid kompileringstidpunkten | Objektets metod åberopas vid körning |
Implementeras vanligtvis med operatörsöverbelastning och funktionsöverbelastning | Implementerad med virtuella funktioner och metodöverstyrning |
Metodöverbelastning är en sammanställningstidspolymorfism där mer än en metod kan ha samma namn men olika parametrar och olika typer. | Metod åsidosättande är runtime polymorfism där mer än en metod har samma namn med samma prototyp |
Eftersom metoder är kända vid kompileringen är körningen snabbare | Körningen är långsammare eftersom metoden är känd vid körning |
Ge mindre flexibilitet för att implementera lösningar eftersom allt behöver vara känt vid sammanställningstid | Mycket mer flexibel för att implementera komplexa lösningar eftersom metoder bestäms vid körning |
Kompilera tidspolymorfism
Kompileringstidspolymorfism är en teknik där ett objekts metod åberopas vid kompileringstiden.
Denna typ av polymorfism implementeras på två sätt.
- Funktionsöverbelastning
- Överbelastning av operatören
Vi kommer att diskutera varje teknik i detalj.
Funktion överbelastning
En funktion sägs vara överbelastad när vi har mer än en funktion med samma namn men olika parametertyper eller ett annat antal argument.
Således kan en funktion överbelastas baserat på parametertyperna, parametrarnas ordning och antalet parametrar.
Observera att två funktioner med samma namn och samma parameterlista men olika returtyp inte är en överbelastad funktion och kommer att resultera i ett kompileringsfel om de används i programmet.
På samma sätt, när funktionsparametrar bara skiljer sig åt i pekaren och om arraytyp är ekvivalent, ska den inte användas för överbelastning.
Andra typer som statisk och icke-statisk, const och flyktig, etc. Eller parameterdeklarationer som skiljer sig i närvaro eller frånvaro av standardvärden ska inte heller användas för överbelastning eftersom de är ekvivalenta ur implementeringssynpunkt.
Till exempel,följande funktionsprototyper är överbelastade funktioner.
Add(int,int); Add(int,float); Add(float,int); Add(int,int,int);
I ovanstående prototyper ser vi att vi överbelastar funktionen Lägg till baserat på typen av parametrar, sekvens eller ordning på parametrar, antal parametrar etc.
Låt oss ta ett fullständigt programmeringsexempel för att bättre förstå funktionsöverbelastning.
#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< Produktion:
35
191
19
Hej världen
I ovanstående program har vi en Summation-klass som definierade tre överbelastade funktioner som heter Add som tar två heltalargument, tre heltalargument och två strängargument.
I huvudfunktionen gör vi fyra funktionsanrop som ger olika parametrar. De två första funktionsanropen är enkla. I det tredje funktionsanropet till Lägg till ger vi två flytande värden som argument.
I det här fallet är funktionen som matchas int Lägg till (int, int) som internt, konverteras flottören till dubbel och matchas sedan med funktionen med int-parametrarna. Om vi hade specificerat dubbel istället för flyt, skulle vi ha en annan överbelastad funktion med dubbla som parametrar.
Det senaste funktionsanropet använder strängvärden som parametrar. I det här fallet fungerar Add (+) -operatören som en sammanfogningsoperator och sammanfogar de två strängvärdena för att producera en enda sträng.
Fördelar med funktionsöverbelastning
Den största fördelen med funktionsöverbelastning är att den främjar återanvändbar kod. Vi kan ha så många funktioner som möjligt med samma namn så länge de är överbelastade baserat på argumenttyp, argumentsekvens och antalet argument.
Genom att göra detta blir det lättare att ha olika funktioner med samma namn för att representera beteendet hos samma operation under olika förhållanden.
Om funktionsöverbelastning inte fanns, skulle vi behöva skriva för många olika typer av funktioner med olika namn, vilket gör koden oläslig och svår att anpassa.
Överbelastning av operatören
Operatörsöverbelastning är den teknik som vi använder en annan innebörd för de befintliga operatörerna i C ++. Med andra ord överbelastar vi operatörerna för att ge de användardefinierade datatyperna en speciell betydelse som objekt.
De flesta operatörer i C ++ är överbelastade eller får särskild betydelse så att de kan arbeta med användardefinierade datatyper. Observera att under överbelastning ändras inte operatörens grundläggande funktion. Överbelastning ger bara operatören en extra mening genom att hålla sin grundläggande semantiska densamma.
Även om de flesta operatörer kan överbelastas i C ++, finns det vissa operatörer som inte kan överbelastas.
Dessa operatörer listas i tabellen nedan.
Operatörer Scope resolution operator (: :) Storlek av medlemsväljare (.) medlemspekerväljare (*) ternär operatör (? :)
Funktionerna som vi använder för att överbelasta operatörer kallas ” Operatörsfunktioner ”.
Operatörsfunktioner liknar de normala funktionerna men med skillnad. Skillnaden är att namnet på operatörsfunktionerna börjar med nyckelordet ” operatör ”Följt av operatörssymbolen som ska överbelastas.
Operatörsfunktionen anropas då när motsvarande operatör används i programmet. Dessa operatörsfunktioner kan vara medlemsfunktionerna eller globala metoder eller till och med en vänfunktion.
Den allmänna syntaxen för operatörsfunktionen är:
return_type classname::operator op(parameter list) { //function body }
Här är 'operatör op' operatörsfunktionen där operatören är nyckelordet och op är operatören som ska överbelastas. Return_type är den värdetyp som ska returneras.
Låt oss se några programmeringsexempel för att visa operatörens överbelastning med operatörsfunktioner.
Exempel 1:Överbelastning av den unary operatören med hjälp av medlemsoperatörsfunktionen.
#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; }
Produktion:
Inkrementerat fotvärde: 10
bästa webbplatsen för att konvertera youtube till mp3
Här har vi överbelastat den unary ökningsoperatören med hjälp av operator ++ -funktionen. I huvudfunktionen använder vi den här ++ operatören för att öka objektet för klass Distans.
Exempel 2:Överbelastning av den binära operatören med hjälp av medlemsoperatörsfunktionen.
#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(); }
Produktion:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Här har vi använt det klassiska exemplet på tillägg av två komplexa nummer med hjälp av operatörens överbelastning. Vi definierar en klass som representerar komplexa nummer och en operatörsfunktion för överbelastning + operator där vi lägger till de verkliga och imaginära delarna av komplexa tal.
I huvudfunktionen deklarerar vi två komplexa objekt och lägger till dem med den överbelastade + -operatören för att få önskat resultat.
I exemplet nedan använder vi vänfunktionen för att lägga till två komplexa nummer för att se skillnaden i implementering.
#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(); }
Produktion:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Vi ser att resultatet av programmet är detsamma. Den enda skillnaden i implementeringen är användningen av vänfunktionen för att överbelasta + -operatören istället för en medlemsfunktion i den tidigare implementeringen.
När vänfunktionen används för en binär operatör måste vi uttryckligen specificera båda operanderna till funktionen. På samma sätt, när den unary operatören är överbelastad med hjälp av vänfunktionen, måste vi tillhandahålla den enda operand till funktionen.
Förutom operatörsfunktionerna kan vi också skriva a konverteringsoperatör som används för att konvertera från en typ till en annan. Dessa överbelastade konverteringsoperatörer bör vara en medlemsfunktion i klassen.
Exempel 3:Överbelastning av operatör med konverteringsoperatör.
#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)= '< Produktion:
Det resulterande värdet för given fraktion (3,5) = 0,6
I det här programmet har vi använt konverteringsoperatören för att konvertera den angivna fraktionen till ett flytvärde. När konverteringen är klar returnerar konverteringsoperatören det resulterande värdet till den som ringer.
I huvudfunktionen, när vi tilldelar df-objektet till en res_val-variabel, sker omvandlingen och resultatet lagras i res_val.
Vi kan också ringa en konstruktör med ett enda argument. När vi kan ringa en konstruktör från klassen med ett enda argument kallas detta för ” omvandling byggare ”. Konverteringskonstruktör kan användas för implicit konvertering till den klass som konstrueras.
#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 = '< Produktion:
Punkt konstruerad med normal konstruktör
x = 20 y = 30
Punkt konstruerad med hjälp av konverteringskonstruktör
x = 10 y = 0

Här har vi en klasspunkt som definierar en konstruktör med standardvärden. I huvudfunktionen konstruerar vi ett objekt pt med x- och y-koordinater. Därefter tilldelar vi bara pt ett värde på 10. Det är där konverteringskonstruktören anropas och x tilldelas ett värde på 10 medan y ges standardvärdet 0.
Regler för överbelastning av operatörer
När operatören överbelastas måste vi se upp nedanstående regler.
- I C ++ kan vi endast överbelasta de befintliga operatörerna. Nyligen tillagda operatörer kan inte överbelastas.
- När operatörer är överbelastade måste vi se till att minst en av operanderna är av den användardefinierade typen.
- För att överbelasta vissa operatörer kan vi också använda vänfunktionen.
- När vi överbelastar unära operatörer som använder en medlemsfunktion, krävs inga uttryckliga argument. Det krävs ett tydligt argument när den unary operatören är överbelastad med hjälp av vänfunktionen.
- På samma sätt, när binära operatörer överbelastas med hjälp av medlemsfunktion, måste vi tillhandahålla ett uttryckligt argument för funktionen. När binära operatörer överbelastas med hjälp av vänfunktionen tar funktionen två argument.
- Det finns två operatörer i C ++ som redan är överbelastade. Dessa är “=” och “&”. För att kopiera ett objekt av samma klass behöver vi därför inte överbelasta operatören =, och vi kan använda det direkt.
Fördelar med överbelastning av operatören
Överbelastning av operatörer i C ++ gör att vi kan utöka operatörernas funktioner till de användardefinierade typerna inklusive klassobjekt utöver de inbyggda typerna.
Genom att utöka operatörsfunktionaliteten till de användardefinierade typerna behöver vi inte skriva komplex kod för att utföra olika operationer på användardefinierade typer, men vi kan göra det i en operation själv precis som de inbyggda typerna.
Slutsats
Kompilera tidspolymorfism ger överbelastningsanläggning främst för att utöka funktionaliteten i koden när det gäller funktionsöverbelastning och operatörsöverbelastning.
Genom funktionsöverbelastning kan vi skriva mer än en funktion med samma namn men olika parametrar och typer. Detta gör koden enkel och lättläst. Genom överbelastning av operatörer kan vi utöka funktionaliteten hos operatörer så att vi också kan utföra grundläggande operationer på användardefinierade typer.
I vår kommande handledning lär vi oss mer om runtime polymorfism i C ++.
=> Läs igenom Easy C ++ Training Series.
Rekommenderad läsning
- Runtime Polymorphism In C ++
- Vänfunktioner i C ++
- Rekursion i C ++
- Pythons huvudfunktionshandledning med praktiska exempel
- En fullständig översikt över C ++
- QTP-handledning # 21 - Hur man gör QTP-tester modulära och återanvändbara med hjälp av åtgärds- och funktionsbibliotek
- Unix Pipes Tutorial: Pipes in Unix Programming
- Biblioteksfunktioner i C ++