polymorphism c
Rolle av polymorfisme i C ++ med eksempler.
Polymorfisme er en av de fire søylene i objektorientert programmering. Polymorfisme betyr å ha mange former. Det kan defineres som teknikken som et objekt kan ta mange former avhengig av situasjonen.
I programmeringsbetingelser kan vi si at et objekt kan oppføre seg annerledes under forskjellige forhold.
I denne opplæringen vil vi lære om typene polymorfisme, måtene å implementere polymorfisme sammen med de forskjellige andre begrepene polymorfisme i detalj.
=> Sjekk her for å se AZ av C ++ opplæringsveiledninger her.
For eksempel, en kvinne kan ta mange roller i forskjellige situasjoner. For et barn er hun mor, hjemmeværende hjemme, arbeidstaker på kontoret osv. Så en kvinne påtar seg forskjellige roller og viser forskjellig oppførsel under forskjellige forhold. Dette er et reelt eksempel på polymorfisme.
På samme måte i programmeringsverdenen kan vi også ha en operator '+' som er den binære tilleggsoperatøren som oppfører seg annerledes når operandene endres. For eksempel, når begge operandene er numeriske, utfører den tillegg.
På den annen side, når operandene er streng, fungerer den som sammenkoblingsoperator. Dermed betyr polymorfisme, i et nøtteskall, en enhet som tar opp mange former eller oppfører seg annerledes under forskjellige forhold.
Hva du vil lære:
- Typer polymorfisme
- Compile Time Polymorphism Vs. Run-Time polymorfisme
- Kompilere tidspolymorfisme
- Funksjon Overbelastning
- Overbelastning av operatør
- Konklusjon
- Anbefalt lesing
Typer polymorfisme
Polymorfisme er delt inn i to typer.
- Kompiler tidspolymorfisme
- Runtime polymorfisme
Diagrammet for å representere dette er vist nedenfor:
Som vist i diagrammet ovenfor, er polymorfisme delt inn i polymorfisme med kompileringstid og polymorfisme under kjøretid. Kompileringstidspolymorfisme er videre delt inn i operatøroverbelastning og funksjonsoverbelastning. Runtime polymorfisme er videre implementert ved hjelp av virtuelle funksjoner.
Kompileringstidspolymorfisme er også kjent som tidlig binding eller statisk polymorfisme. I denne typen polymorfisme blir objektets metode påkalt på kompileringstidspunktet. I tilfelle av kjøretidspolymorfisme, blir objektets metode påkalt på kjøretid.
Runtime polymorfisme er også kjent som dynamisk eller sen binding eller dynamisk polymorfisme. Vi vil se på detaljert implementering av hver av disse teknikkene i de følgende emnene våre.
Compile Time Polymorphism Vs. Run-Time polymorfisme
La oss se de viktigste forskjellene mellom kompileringstid og polymorfisme under kjøretid nedenfor.
Kompiler tidspolymorfisme | Runtime polymorfisme |
---|---|
Også kjent som statisk polymorfisme eller tidlig binding | Også kjent som dynamisk polymorfisme eller sen / dynamisk binding |
Objektmetoden påkalles ved kompileringstidspunktet | Objektets metode påkalles på kjøretid |
Vanligvis implementert ved bruk av operatøroverbelastning og funksjonsoverbelastning | Implementert ved hjelp av virtuelle funksjoner og metodeoverstyring |
Metodeoverbelastning er en kompileringstidspolymorfisme der mer enn én metode kan ha samme navn, men forskjellige parameterlister og typer. | Metodeoverstyring er runtime polymorfisme der mer enn en metode har samme navn med samme prototype |
Siden metoder er kjent på kompileringstidspunktet, er utførelsen raskere | Utførelsen er tregere siden metoden er kjent på kjøretid |
Gi mindre fleksibilitet til å implementere løsninger siden alt trenger å være kjent på kompileringstidspunktet | Langt mer fleksibelt for implementering av komplekse løsninger ettersom metoder blir bestemt i løpetid |
Kompilere tidspolymorfisme
Kompileringstidspolymorfisme er en teknikk der et objekts metode påkalles på kompileringstiden.
Denne typen polymorfisme er implementert på to måter.
- Funksjon overbelastning
- Overbelastning av operatøren
Vi vil diskutere hver teknikk i detalj.
Funksjon Overbelastning
En funksjon sies å være overbelastet når vi har mer enn en funksjon med samme navn, men forskjellige parametertyper eller et annet antall argumenter.
Dermed kan en funksjon overbelastes basert på parametertypene, rekkefølgen på parametere og antall parametere.
Vær oppmerksom på at to funksjoner med samme navn og samme parameterliste, men forskjellige returtype, ikke er en overbelastet funksjon, og vil resultere i en kompileringsfeil hvis de brukes i programmet.
På samme måte, når funksjonsparametere bare avviker i peker, og hvis matrisen er ekvivalent, bør den ikke brukes til overbelastning.
Andre typer som statisk og ikke-statisk, const og flyktig osv. Eller parametererklæringer som varierer i nærvær eller fravær av standardverdier, skal heller ikke brukes til overbelastning, da de er ekvivalente fra implementeringssynspunktet.
For eksempel,følgende funksjonsprototyper er overbelastede funksjoner.
Add(int,int); Add(int,float); Add(float,int); Add(int,int,int);
I prototypene ovenfor ser vi at vi overbelaster funksjonen Add basert på parametertypen, rekkefølgen eller rekkefølgen på parametere, antall parametere osv.
La oss ta et komplett programmeringseksempel for å bedre forstå funksjonen Overbelastning.
#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< Produksjon:
35
191
19
Hei Verden
I det ovennevnte programmet har vi en Summation-klasse som definerte tre overbelastede funksjoner kalt Add som tar to heltallargumenter, tre heltallargumenter og to strengargumenter.
I hovedfunksjonen lager vi fire funksjonsanrop som gir forskjellige parametere. De to første funksjonsanropene er greie. I den tredje funksjonsanropet til Add, gir vi to flytende punktverdier som argumenter.
I dette tilfellet er funksjonen som er matchet int Add (int, int) som internt, flottøren konverteres til dobbelt og deretter matches med funksjonen med int-parametrene. Hvis vi hadde spesifisert dobbelt i stedet for å flyte, ville vi ha en annen overbelastet funksjon med dobbelt som parametere.
Den siste funksjonsanropet bruker strengverdier som parametere. I dette tilfellet fungerer Add (+) -operatøren som en sammenkoblingsoperator og sammenkobler de to strengverdiene for å produsere en enkelt streng.
Fordeler med funksjonsoverbelastning
Den største fordelen med funksjonsoverbelastning er at den fremmer gjenbrukbar kode. Vi kan ha så mange funksjoner som mulig med samme navn så lenge de er overbelastet basert på argumenttype, argumentrekkefølge og antall argumenter.
Ved å gjøre dette blir det lettere å ha forskjellige funksjoner med samme navn for å representere oppførselen til den samme operasjonen under forskjellige forhold.
Hvis funksjonsoverbelastning ikke var til stede, ville vi måtte skrive for mange forskjellige typer funksjoner med forskjellige navn, og dermed gjøre koden uleselig og vanskelig å tilpasse.
Overbelastning av operatør
Operatøroverbelastning er teknikken der vi gir en annen betydning til de eksisterende operatørene i C ++. Vi overbelaster med andre ord operatørene for å gi de brukerdefinerte datatypene en spesiell betydning som objekter.
De fleste operatørene i C ++ er overbelastet eller får spesiell betydning slik at de kan jobbe med brukerdefinerte datatyper. Merk at mens overbelastning ikke blir den grunnleggende operasjonen til operatørene endret. Overbelastning gir bare operatøren en ekstra betydning ved å holde den grunnleggende semantiske.
Selv om de fleste operatører kan overbelastes i C ++, er det noen operatører som ikke kan overbelastes.
Disse operatørene er oppført i tabellen nedenfor.
Operatører Omfangsoppløsningsoperatør (: :) Størrelsen av medlemsvelger (.) medlemspekervelger (*) ternær operatør (? :)
Funksjonene vi bruker for å overbelaste operatører kalles “ Operatørfunksjoner ”.
Operatørfunksjonene ligner på de vanlige funksjonene, men med forskjell. Forskjellen er at navnet på operatørfunksjonene begynner med nøkkelordet “ operatør ”Etterfulgt av operatørsymbolet som skal overbelastes.
Operatørfunksjonen blir da ringt opp når den tilsvarende operatøren brukes i programmet. Disse operatørfunksjonene kan være medlemsfunksjonene eller globale metoder eller til og med en vennefunksjon.
Den generelle syntaksen til operatørfunksjonen er:
return_type classname::operator op(parameter list) { //function body }
Her er 'operatør op' operatørfunksjonen der operatøren er nøkkelordet og op er operatøren som skal overbelastes. Return_type er verditypen som skal returneres.
La oss se noen programmeringseksempler for å demonstrere operatørens overbelastning ved hjelp av operatørfunksjoner.
brukerhistorier eksempler med akseptkriterier
Eksempel 1:Overbelastning av den unære operatøren ved hjelp av medlemsoperatørfunksjonen.
#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; }
Produksjon:
Inkrementert fotverdi: 10
Her har vi overbelastet den unary økningsoperatøren ved hjelp av operator ++ -funksjonen. I hovedfunksjonen bruker vi denne ++ operatoren til å øke objektet til klassen Distance.
Eksempel 2:Overbelastning av binæroperatøren ved bruk av medlemsoperatørfunksjonen.
#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(); }
Produksjon:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Her har vi brukt det klassiske eksemplet på tillegg av to komplekse tall ved bruk av overbelastning av operatøren. Vi definerer en klasse som skal representere komplekse tall og en operatørfunksjon for å overbelaste + operator der vi legger til de virkelige og imaginære delene av komplekse tall.
I hovedfunksjonen erklærer vi to komplekse objekter og legger til dem ved hjelp av den overbelastede + -operatøren for å få ønsket resultat.
I eksemplet nedenfor vil vi bruke vennefunksjonen til å legge til to komplekse tall for å se forskjellen 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(); }
Produksjon:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Vi ser at resultatet av programmet er det samme. Den eneste forskjellen i implementeringen er bruken av vennefunksjon for å overbelaste + -operatøren i stedet for en medlemsfunksjon i forrige implementering.
Når vennefunksjon brukes for en binær operatør, må vi eksplisitt spesifisere begge operandene til funksjonen. På samme måte, når den unære operatøren er overbelastet ved hjelp av vennefunksjonen, må vi gi den ene operanden til funksjonen.
Bortsett fra operatørfunksjonene, kan vi også skrive en konverteringsoperatør som brukes til å konvertere fra en type til en annen. Disse overbelastede konverteringsoperatørene bør være en medlemsfunksjon i klassen.
Eksempel 3:Overbelastning av operatør ved hjelp av 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)= '< Produksjon:
Den resulterende verdien av gitt brøkdel (3,5) = 0,6
I dette programmet har vi brukt konverteringsoperatøren til å konvertere den gitte brøk til en flytverdi. Når konverteringen er ferdig, returnerer konverteringsoperatøren den resulterende verdien til innringeren.
I hovedfunksjonen, når vi tilordner df-objektet til en res_val-variabel, finner konverteringen sted og resultatet lagres i res_val.
Vi kan også kalle en konstruktør med et enkelt argument. Når vi kan ringe en konstruktør fra klassen ved hjelp av et enkelt argument, kalles dette en “ omdannelse bygger ”. Konverteringskonstruktør kan brukes til implisitt konvertering til klassen som konstrueres.
#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 = '< Produksjon:
Punkt konstruert ved bruk av normal konstruktør
x = 20 y = 30
Punkt konstruert ved hjelp av konverteringskonstruktør
x = 10 y = 0
Her har vi et klassepunkt som definerer en konstruktør med standardverdier. I hovedfunksjonen konstruerer vi et objekt pt med x- og y-koordinater. Deretter tildeler vi bare pt en verdi på 10. Dette kalles konverteringskonstruktøren og x tildeles en verdi på 10 mens y får standardverdien 0.
Regler for overbelastning av operatører
Når vi utfører overbelastning av operatører, må vi passe på reglene nedenfor.
- I C ++ kan vi bare overbelaste eksisterende operatører. Nylig tilføyde operatører kan ikke overbelastes.
- Når operatører er overbelastet, må vi sørge for at minst en av operandene er av den brukerdefinerte typen.
- For å overbelaste visse operatører, kan vi også bruke vennefunksjon.
- Når vi overbelaster unære operatører som bruker en medlemsfunksjon, tar det ingen eksplisitte argumenter. Det krever ett eksplisitt argument når den unary operatøren er overbelastet ved hjelp av vennefunksjonen.
- På samme måte, når binære operatører er overbelastet ved hjelp av medlemsfunksjon, må vi gi et eksplisitt argument til funksjonen. Når binære operatører er overbelastet ved hjelp av vennefunksjonen, tar funksjonen to argumenter.
- Det er to operatører i C ++ som allerede er overbelastet. Dette er “=” og “&”. Derfor trenger vi ikke å overbelaste = operatøren for å kopiere et objekt av samme klasse, og vi kan bruke det direkte.
Fordeler med overbelastning av operatøren
Operatøroverbelastning i C ++ lar oss utvide funksjonaliteten til operatører til de brukerdefinerte typene, inkludert klasseobjekter i tillegg til de innebygde typene.
Ved å utvide operatørfunksjonaliteten til de brukerdefinerte typene, trenger vi ikke skrive kompleks kode for å utføre forskjellige operasjoner på brukerdefinerte typer, men vi kan gjøre det i en operasjon selv, akkurat som de innebygde typene.
Konklusjon
Kompileringstidspolymorfisme gir overbelastningsanlegg hovedsakelig for å utvide kodens funksjonalitet når det gjelder funksjonsoverbelastning og operatøroverbelastning.
Gjennom funksjonsoverbelastning kan vi skrive mer enn en funksjon med samme navn, men forskjellige parametere og typer. Dette gjør koden enkel og lett lesbar. Ved å overbelaste operatørene kan vi utvide funksjonaliteten til operatørene, slik at vi også kan utføre grunnleggende operasjoner på brukerdefinerte typer.
I vår kommende opplæring vil vi lære mer om runtime polymorfisme i C ++.
=> Les gjennom Easy C ++ Training Series.
Anbefalt lesing
- Runtime Polymorphism In C ++
- Vennfunksjoner i C ++
- Rekursjon i C ++
- Python hovedveiledning med praktiske eksempler
- En komplett oversikt over C ++
- QTP Opplæring # 21 - Hvordan lage QTP-tester modulære og gjenbrukbare ved hjelp av handlinger og funksjonsbiblioteker
- Unix Pipes Tutorial: Pipes in Unix Programming
- Biblioteksfunksjoner i C ++