polymorphism c
Polymorfismens rolle i C ++ med eksempler.
Polymorfisme er en af de fire søjler i objektorienteret programmering. Polymorfisme betyder at have mange former. Det kan defineres som den teknik, hvormed et objekt kan tage mange former afhængigt af situationen.
I programmeringsbetingelser kan vi sige, at et objekt kan opføre sig forskelligt under forskellige forhold.
I denne vejledning lærer vi om typerne af polymorfisme, måderne til at implementere polymorfisme sammen med de forskellige andre begreber polymorfisme i detaljer.
=> Tjek her for at se AZ af C ++ træningsvejledninger her.
For eksempel, en kvinde kan tage mange roller i forskellige situationer. For et barn er hun mor, hjemmeværende hjemme, arbejdstager på kontoret osv. Så en kvinde påtager sig forskellige roller og udviser forskellig opførsel under forskellige forhold. Dette er et virkeligt eksempel på polymorfisme.
På samme måde i programmeringsverdenen kan vi også have en operator '+', der er den binære additionsoperator, der opfører sig anderledes, når operanderne ændres. For eksempel, når begge operander er numeriske, udfører den tilføjelse.
forskelle mellem c ++ og java
På den anden side fungerer operanderne som sammenkædningsoperator, når operanderne er streng. Således betyder polymorfisme i en nøddeskal en enhed, der tager mange former eller opfører sig forskelligt under forskellige forhold.
Hvad du lærer:
- Typer af polymorfisme
- Compile Time Polymorphism Vs. Kørselstidspolymorfisme
- Kompilér tidspolymorfisme
- Funktion Overbelastning
- Operatør Overbelastning
- Konklusion
- Anbefalet læsning
Typer af polymorfisme
Polymorfisme er opdelt i to typer.
- Kompilér tidspolymorfisme
- Runtime polymorfisme
Diagrammet til at repræsentere dette er vist nedenfor:
Som vist i ovenstående diagram er polymorfisme opdelt i kompileringstidspolymorfisme og runtime polymorfisme. Kompileringstidspolymorfisme er yderligere opdelt i operatøroverbelastning og funktionsoverbelastning. Runtime polymorfisme implementeres yderligere ved hjælp af virtuelle funktioner.
Kompileringstidspolymorfisme er også kendt som tidlig binding eller statisk polymorfisme. I denne type polymorfisme påberåbes objektets metode på kompileringstidspunktet. I tilfælde af runtime polymorfisme påberåbes objektets metode på kørselstidspunktet.
Runtime polymorfisme er også kendt som dynamisk eller sen binding eller dynamisk polymorfisme. Vi vil se på den detaljerede implementering af hver af disse teknikker i vores følgende emner.
Compile Time Polymorphism Vs. Kørselstidspolymorfisme
Lad os se de vigtigste forskelle mellem kompileringstid og runtime polymorfisme nedenfor.
Kompilér tidspolymorfisme | Runtime polymorfisme |
---|---|
Også kendt som statisk polymorfisme eller tidlig binding | Også kendt som dynamisk polymorfisme eller sen / dynamisk binding |
Objektmetoden påberåbes på kompileringstidspunktet | Objektets metode påberåbes ved kørselstid |
Normalt implementeret ved hjælp af operatøroverbelastning og funktionsoverbelastning | Implementeret ved hjælp af virtuelle funktioner og metodeoverstyring |
Metodeoverbelastning er en kompileringstidspolymorfisme, hvor mere end en metode kan have samme navn, men forskellige parameterlister og -typer. | Metodeoverstyring er runtime polymorfisme, hvor mere end en metode har samme navn med den samme prototype |
Da metoder er kendt på kompileringstidspunktet, er udførelsen hurtigere | Udførelsen er langsommere, da metoden er kendt under kørsel |
Giv mindre fleksibilitet til at implementere løsninger, da alt skal være kendt på kompileringstidspunktet | Langt mere fleksibel til implementering af komplekse løsninger, da metoder afgøres i løbetid |
Kompilér tidspolymorfisme
Kompileringstidspolymorfisme er en teknik, hvor et objekts metode påberåbes på kompileringstidspunktet.
Denne type polymorfisme implementeres på to måder.
- Funktion overbelastning
- Operatør overbelastning
Vi vil diskutere hver teknik detaljeret.
Funktion Overbelastning
En funktion siges at være overbelastet, når vi har mere end en funktion med samme navn, men forskellige parametertyper eller et andet antal argumenter.
Således kan en funktion overbelastes baseret på parametertyperne, rækkefølgen af parametre og antallet af parametre.
Bemærk, at to funktioner med samme navn og samme parameterliste, men forskellige returtyper, ikke er en overbelastet funktion og vil resultere i en kompileringsfejl, hvis de bruges i programmet.
På samme måde, når funktionsparametre kun adskiller sig i markør, og hvis array-typen er ækvivalent, skal den ikke bruges til overbelastning.
Andre typer som statisk og ikke-statisk, const og flygtig osv. Eller parametererklæringer, der adskiller sig i tilstedeværelse eller fravær af standardværdier, skal heller ikke bruges til overbelastning, da de er ækvivalente fra implementeringssynspunktet.
For eksempel,følgende funktionsprototyper er overbelastede funktioner.
Add(int,int); Add(int,float); Add(float,int); Add(int,int,int);
I ovenstående prototyper ser vi, at vi overbelaster funktionen Tilføj baseret på typen af parametre, rækkefølge eller rækkefølge af parametre, antal parametre osv.
Lad os tage et komplet programmeringseksempel for bedre at forstå funktionsoverbelastning.
#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 Verden
I ovenstående program har vi en Summation-klasse, der definerede tre overbelastede funktioner ved navn Add, der tager to heltalargumenter, tre heltalargumenter og to strengargumenter.
I hovedfunktionen foretager vi fire funktionsopkald, der giver forskellige parametre. De to første funktionsopkald er ligetil. I det tredje funktionsopkald til Tilføj leverer vi to flydende punktværdier som argumenter.
I dette tilfælde er den funktion, der matches, int tilføj (int, int) som internt, flyderen konverteres til dobbelt og matches derefter med funktionen med int-parametrene. Hvis vi havde angivet dobbelt i stedet for float, ville vi have en anden overbelastet funktion med dobbelt som parametre.
Det sidste funktionsopkald bruger strengværdier som parametre. I dette tilfælde fungerer Add (+) -operatoren som en sammenkædningsoperator og sammenkæder de to strengværdier for at producere en enkelt streng.
Fordele ved funktionsoverbelastning
Den største fordel ved funktionsoverbelastning er, at det fremmer genanvendelighed af kode. Vi kan have så mange funktioner som muligt med det samme navn, så længe de er overbelastede baseret på argumenttypen, argumentsekvensen og antallet af argumenter.
Ved at gøre dette bliver det lettere at have forskellige funktioner med samme navn til at repræsentere opførelsen af den samme operation under forskellige forhold.
Hvis funktionsoverbelastning ikke var til stede, ville vi have været nødt til at skrive for mange forskellige slags funktioner med forskellige navne, hvilket gør koden ulæselige og vanskelige at tilpasse.
Operatør Overbelastning
Operatøroverbelastning er den teknik, hvor vi giver en anden betydning til de eksisterende operatører i C ++. Med andre ord overbelaster vi operatørerne for at give de brugerdefinerede datatyper en særlig betydning som objekter.
De fleste operatører i C ++ er overbelastede eller får en særlig betydning, så de kan arbejde på brugerdefinerede datatyper. Bemærk, at under overbelastning ændres operatørens grundlæggende funktion ikke. Overbelastning giver operatøren bare en ekstra betydning ved at holde deres grundlæggende semantiske ens.
Selvom de fleste operatører kan overbelastes i C ++, er der nogle operatører, som ikke kan overbelastes.
Disse operatører er angivet i nedenstående tabel.
Operatører Omfangsopløsningsoperator (: :) Størrelse af medlemsvælger (.) medlemsvælgervælger (*) ternær operatør (? :)
De funktioner, vi bruger til at overbelaste operatører, kaldes “ Operatørfunktioner ”.
Operatørfunktioner svarer til de normale funktioner, men med forskel. Forskellen er, at navnet på operatørfunktionerne begynder med nøgleordet “ operatør ”Efterfulgt af operatørsymbolet, der skal overbelastes.
Operatørfunktionen kaldes derefter op, når den tilsvarende operatør bruges i programmet. Disse operatørfunktioner kan være medlemsfunktionerne eller globale metoder eller endda en venfunktion.
Den generelle syntaks for operatørfunktionen er:
return_type classname::operator op(parameter list) { //function body }
Her er 'operatør op' operatørfunktionen, hvor operatøren er nøgleordet, og op er operatøren, der skal overbelastes. Return_type er den værditype, der skal returneres.
Lad os se få programmeringseksempler til demonstration af operatørens overbelastning ved hjælp af operatørfunktioner.
Eksempel 1:Overbelastning af den unære operatør ved hjælp af medlemsoperatørfunktion.
#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:
Forhøjet fodværdi: 10
Her har vi overbelastet den unære stigningsoperator ved hjælp af operator ++ -funktionen. I hovedfunktionen bruger vi denne ++ operator til at øge objektet til klasse Distance.
Eksempel 2:Overbelastning af den binære operatør ved hjælp af medlemsoperatørfunktionen.
#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
Her har vi brugt det klassiske eksempel på tilføjelsen af to komplekse tal ved hjælp af operatørens overbelastning. Vi definerer en klasse til at repræsentere komplekse tal og en operatorfunktion til overbelastning + operator, hvor vi tilføjer de reelle og imaginære dele af komplekse tal.
I hovedfunktionen erklærer vi to komplekse objekter og tilføjer dem ved hjælp af den overbelastede + operator for at få det ønskede resultat.
I nedenstående eksempel bruger vi venfunktionen til at tilføje to komplekse tal for at se forskellen i implementeringen.
#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, at output fra programmet er det samme. Den eneste forskel i implementeringen er brugen af venfunktion til at overbelaste + -operatøren i stedet for en medlemsfunktion i den foregående implementering.
Når venfunktion bruges til en binær operatør, skal vi eksplicit angive begge operanderne til funktionen. På samme måde, når den unære operatør er overbelastet ved hjælp af venfunktionen, er vi nødt til at give den enkelte operand til funktionen.
Bortset fra operatørfunktionerne kan vi også skrive en konverteringsoperatør der bruges til at konvertere fra en type til en anden. Disse overbelastede konverteringsoperatører skal være en medlemsfunktion i klassen.
Eksempel 3:Operatøroverbelastning ved hjælp af 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:
Den resulterende værdi af en given brøkdel (3,5) = 0,6
I dette program har vi brugt konverteringsoperatøren til at konvertere den givne brøk til en flydeværdi. Når konverteringen er udført, returnerer konverteringsoperatøren den resulterende værdi til den, der ringer op.
I hovedfunktionen, når vi tildeler df-objektet til en res_val-variabel, finder konverteringen sted, og resultatet lagres i res_val.
Vi kan også kalde en konstruktør med et enkelt argument. Når vi kan kalde en konstruktør fra klassen ved hjælp af et enkelt argument, kaldes dette et ” konvertering Bygger ”. Konverteringskonstruktør kan bruges til implicit konvertering til den klasse, der 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 = '< Produktion:
Punkt konstrueret ved hjælp af normal konstruktør
x = 20 y = 30
Punkt konstrueret ved hjælp af konverteringskonstruktør
x = 10 y = 0

Her har vi et klassepunkt, der definerer en konstruktør med standardværdier. I hovedfunktionen konstruerer vi et objekt pt med x- og y-koordinater. Derefter tildeler vi bare pt en værdi på 10. Dette kaldes konverteringskonstruktøren, og x tildeles en værdi på 10, mens y får standardværdien 0.
Regler for overbelastning af operatører
Mens vi udfører overbelastning af operatører, skal vi holde øje med nedenstående regler.
- I C ++ kan vi kun overbelaste de eksisterende operatører. Nyligt tilføjede operatører kan ikke overbelastes.
- Når operatører er overbelastede, skal vi sikre, at mindst en af operanderne er af den brugerdefinerede type.
- For at overbelaste visse operatører kan vi også bruge venfunktionen.
- Når vi overbelaster unære operatører ved hjælp af en medlemsfunktion, kræver det ikke eksplicit argumenter. Det kræver et eksplicit argument, når den unære operatør er overbelastet ved hjælp af venfunktionen.
- Tilsvarende, når binære operatører er overbelastet ved hjælp af medlemsfunktion, skal vi give et eksplicit argument til funktionen. Når binære operatører overbelastes ved hjælp af venfunktionen, tager funktionen to argumenter.
- Der er to operatører i C ++, der allerede er overbelastede. Disse er “=” og “&”. Derfor skal vi ikke overbelaste = operatoren for at kopiere et objekt af samme klasse, og vi kan bruge det direkte.
Fordele ved overbelastning af operatøren
Operatøroverbelastning i C ++ giver os mulighed for at udvide funktionaliteten af operatører til de brugerdefinerede typer inklusive klasseobjekter ud over de indbyggede typer.
Ved at udvide operatørfunktionaliteten til de brugerdefinerede typer behøver vi ikke skrive kompleks kode for at udføre forskellige operationer på brugerdefinerede typer, men vi kan gøre det i en operation selv ligesom de indbyggede typer.
Konklusion
Kompileringstidspolymorfisme giver overbelastningsfacilitet hovedsageligt for at udvide kodens funktionalitet med hensyn til funktionsoverbelastning og operatøroverbelastning.
Gennem funktionsoverbelastning kan vi skrive mere end en funktion med samme navn, men forskellige parametre og typer. Dette gør koden enkel og let læselig. Ved overbelastning af operatører kan vi udvide operatørernes funktionalitet, så vi også kan udføre grundlæggende operationer på brugerdefinerede typer.
I vores kommende tutorial lærer vi mere om runtime polymorfisme i C ++.
=> Læs gennem Easy C ++ træningsserien.
Anbefalet læsning
- Runtime polymorfisme i C ++
- Venfunktioner i C ++
- Rekursion i C ++
- Pythons hovedfunktionsvejledning med praktiske eksempler
- En komplet oversigt over C ++
- QTP-tutorial # 21 - Sådan oprettes QTP-tests modulært og genanvendeligt ved hjælp af handlinger og funktionsbiblioteker
- Unix Pipes Tutorial: Pipes in Unix Programming
- Biblioteksfunktioner i C ++