Hva er polymorfisme i C ++?
I C ++ får polymorfisme en medlemsfunksjon til å oppføre seg annerledes basert på objektet som kaller / påkaller det. Polymorfisme er et gresk ord som betyr å ha mange former. Det oppstår når du har et hierarki av klasser relatert gjennom arv.
Anta for eksempel at vi har funksjonen makeSound (). Når en katt kaller denne funksjonen, vil den produsere mjaulyden. Når en ku påkaller den samme funksjonen, vil den gi moow-lyden.
Selv om vi har en funksjon, oppfører den seg annerledes under forskjellige omstendigheter. Funksjonen har mange former; derfor har vi oppnådd polymorfisme.
I denne C ++ opplæringen vil du lære:
- Hva er polymorfisme?
- Typer polymorfisme
- Kompilere tidspolymorfisme
- Funksjon Overbelastning
- Overbelastning av operatør
- Runtime polymorfisme
- Funksjon Overstyring
- C ++ virtuell funksjon
- Kompileringstidspolymorfisme vs. Run-Time polymorfisme
Typer polymorfisme
C ++ støtter to typer polymorfisme:
- Kompileringstidspolymorfisme, og
- Runtime polymorfisme.
Kompilere tidspolymorfisme
Du påberoper deg de overbelastede funksjonene ved å matche antall og type argumenter. Informasjonen er til stede under kompileringstiden. Dette betyr at C ++ kompilatoren velger riktig funksjon på kompileringstidspunktet.
Kompileringstidspolymorfisme oppnås gjennom funksjonsoverbelastning og operatøroverbelastning.
Funksjon Overbelastning
Funksjonsoverbelastning oppstår når vi har mange funksjoner med lignende navn, men forskjellige argumenter. Argumentene kan variere med hensyn til antall eller type.
Eksempel 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;}
Produksjon:
Her er et skjermbilde av koden:
Kode Forklaring:
- Inkluder iostream header-filen i koden vår. Vi vil kunne bruke funksjonene.
- Inkluder std navneområdet i koden vår. Vi vil kunne bruke klassene sine uten å kalle det.
- Opprett en funksjon som heter test som tar et heltallsparameter i. {Markerer begynnelsen på funksjonstesten.
- Erklæring som skal utføres hvis ovennevnte funksjonstest påkalles / kalles.
- Slutten på kroppen av funksjonstesten ovenfor.
- Opprett en funksjon som heter test som tar en flottørparameter f. {Markerer begynnelsen på funksjonstesten.
- Erklæring som skal utføres hvis ovennevnte funksjonstest påkalles / kalles.
- Slutten av kroppen til funksjonstesten ovenfor.
- Opprett en funksjon med navnet test som tar en tegnparameter ch. {Markerer begynnelsen på funksjonstesten.
- Erklæring som skal utføres hvis ovennevnte funksjonstest påkalles / kalles.
- Slutten av kroppen til funksjonstesten ovenfor.
- Ring til hovedfunksjonen (). {Markerer begynnelsen på kroppens funksjon.
- Kall funksjonstesten og send 5 til den som verdien av argumentet. Dette påkaller testfunksjonen som godtar et heltallargument, det vil si den første testfunksjonen.
- Kall funksjonstesten og send 5.5 til den som verdien av argumentet. Dette vil påkalle testfunksjonen som godtar et float-argument, det vil si den andre testfunksjonen.
- Kall funksjonstesten og send fem til den som verdien av argumentet. Dette vil påkalle testfunksjonen som godtar et tegnargument, det vil si den tredje testfunksjonen.
- Programmet må returnere en verdi hvis det kjører vellykket.
- Slutten av kroppen til hovedfunksjonen ().
Vi har tre funksjoner med samme navn, men forskjellige typer argumenter. Vi har oppnådd polymorfisme.
Overbelastning av operatør
I operatøroverbelastning definerer vi en ny betydning for en C ++ - operatør. Det endrer også hvordan operatøren jobber. For eksempel kan vi definere + -operatøren for å sammenkoble to strenger. Vi kjenner det som tilleggsoperatøren for å legge til numeriske verdier. Etter vår definisjon, når den plasseres mellom heltall, vil den legge dem til. Når den plasseres mellom strengene, vil den sammenkoble dem.
Eksempel 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();}
Produksjon:
Her er et skjermbilde av koden:
Kode Forklaring:
- Inkluder iostream header-filen i programmet vårt for å kunne bruke funksjonene.
- Inkluder std navneområdet i programmet vårt for å kunne bruke klassene uten å kalle det.
- Opprett en klasse som heter ComplexNum. {Markerer begynnelsen på klassens kropp.
- Bruk den private tilgangsmodifikatoren til å merke variabler som private, noe som betyr at de bare er tilgjengelige fra klassen.
- Definer to heltallvariabler, reelle og over.
- Bruk modifikatoren for offentlig tilgang til å merke konstruktøren som offentlig, noe som betyr at den vil være tilgjengelig selv fra utenfor klassen.
- Lag klassekonstruktøren og initialiser variablene.
- Initialiser verdien av variabelen reell.
- Initialiser verdien av variabelen over.
- Slutten på konstruktørorganet.
- Vi må overstyre betydningen av + -operatøren.
- Opprett datatyperesultatet av typen ComplexNum.
- Bruk + -operatøren med komplekse tall. Denne linjen vil legge til den virkelige delen av et tall til den virkelige delen av et annet nummer.
- Bruk + -operatøren med komplekse tall. Denne linjen vil legge til den imaginære delen av et tall til den imaginære delen av et annet nummer.
- Programmet returnerer verdien av det variable resultatet etter vellykket gjennomføring.
- Slutt på definisjonen av den nye betydningen av + operator, det vil si overbelastning.
- Ring utskriftsmetoden ().
- Skriv ut det nye komplekse nummeret etter tillegget på konsollen.
- Slutt på funksjonen for utskrift ().
- Slutten av kroppen til ComplexNum-klassen.
- Ring til hovedfunksjonen ().
- Gi verdiene til både virkelige og komplekse deler som skal legges til. Den første delen av c1 vil bli lagt til den første delen av c2, det vil si 10 + 3. Den andre delen av c1 vil bli lagt til den andre delen av c, det vil si 2 + 7.
- Utfør en operasjon ved hjelp av den overbelastede + -operatøren og lagre resultatet i variabel c3.
- Skriv ut verdien av variabelen c3 på konsollen.
- Slutten av kroppen til hovedfunksjonen ().
Runtime polymorfisme
Dette skjer når et objekts metode blir påkalt / kalt i løpet av kjøretiden i stedet for under kompileringstiden. Runtime polymorfisme oppnås gjennom funksjonsoverstyring. Funksjonen som skal kalles / påkalles er etablert under kjøretiden.
Funksjon Overstyring
Overstyring av funksjoner oppstår når en funksjon av baseklassen får en ny definisjon i en avledet klasse. På den tiden kan vi si at grunnfunksjonen har blitt overstyrt.
For eksempel:
#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;}
Produksjon:
Her er et skjermbilde av koden:
Kode Forklaring:
- Importer iostream header-filen til programmet vårt for å bruke funksjonene.
- Inkluder std navneområdet i programmet vårt for å kunne bruke klassene uten å kalle det.
- Lag en klasse som heter Pattedyr. {Markerer begynnelsen på klassens kropp.
- Bruk modifikatoren for offentlig tilgang til å stille funksjonen vi skal lage som offentlig tilgjengelig. Det vil være tilgjengelig fra utenfor denne klassen.
- Opprett en offentlig funksjon som heter eat. {Markerer begynnelsen på funksjonsdelen.
- Skriv ut uttalelsen som er lagt til cout-funksjonen når funksjonen eat () påberopes.
- Slutten av funksjonskroppen spiser ().
- Slutten på kroppen til klassen Pattedyr.
- Lag en klasse med navnet Cow som arver Mammal-klassen. Ku er den avledede klassen, mens Pattedyr er basisklassen. {Markerer begynnelsen på denne klassen.
- Bruk modifikatoren for offentlig tilgang for å merke funksjonen vi skal lage som offentlig tilgjengelig. Det vil være tilgjengelig fra utenfor denne klassen.
- Overstyr funksjonen eat () som ble definert i basisklassen. {Markerer begynnelsen på funksjonsdelen.
- Uttalelsen som skal skrives ut på konsollen når denne funksjonen påkalles.
- Slutten av kroppen til funksjonen spis ().
- Slutten på kroppen til klassen Ku.
- Ring til hovedfunksjonen (). {Markerer begynnelsen på kroppen til denne funksjonen.
- Opprett en forekomst av Cow-klassen og gi den navnet c.
- Kall funksjonen eat () definert i Cow-klassen.
- Programmet må returnere en verdi etter vellykket gjennomføring.
- Slutt på hovedfunksjonen ().
C ++ virtuell funksjon
En virtuell funksjon er en annen måte å implementere kjøretidspolymorfisme i C ++. Det er en spesiell funksjon definert i en basisklasse og omdefinert i den avledede klassen. For å erklære en virtuell funksjon, bør du bruke det virtuelle nøkkelordet. Nøkkelordet skal gå foran erklæringen om funksjonen i basisklassen.
Hvis en virtuell funksjonsklasse blir arvet, omdefinerer den virtuelle klassen den virtuelle funksjonen slik at den passer til dens behov. For eksempel:
#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();}
Produksjon:
Her er et skjermbilde av koden:
Kode Forklaring:
- Inkluder iostream header-filen i koden for å bruke funksjonene.
- Inkluder std navneområdet i koden vår for å bruke klassene uten å kalle det.
- Opprett en klasse som heter ClassA.
- Bruk modifikatoren for offentlig tilgang til å markere et klassemedlem som offentlig tilgjengelig.
- Opprett en virtuell funksjon med navnet show (). Det blir en offentlig funksjon.
- Teksten som skal skrives ut når forestillingen () påberopes, blir påkalt. Endl er et C ++ nøkkelord, som betyr sluttlinje. Den beveger musepekeren til neste linje.
- Slutten på kroppen til det virtuelle funksjonsprogrammet ().
- Slutten på kroppen i klasse ClassA.
- Opprette en ny klasse med navnet ClassB som arver klassen ClassA. ClassA blir basisklassen mens ClassB blir den avledede klassen.
- Bruk modifikatoren for offentlig tilgang til å markere et klassemedlem som offentlig tilgjengelig.
- Omdefinere det virtuelle funksjonsprogrammet () avledet i basisklassen.
- Teksten som skal skrives ut på konsollen når funksjonen show () som er definert i den avledede klassen, blir påkalt.
- Slutten av kroppen til show () -funksjonen.
- Slutten av kroppen til den avledede klassen, klasseB.
- Ring til hovedfunksjonen (). Programlogikken skal legges til i kroppen.
- Opprett en pekervariabel kalt a. Det peker på klassen som heter ClassA.
- Opprett en forekomst av klassen som heter ClassB. Forekomsten får navnet b.
- Tilordne verdilagringene i adressen b i variabelen a.
- Påkalle show () -funksjonen definert i den avledede klassen. Sen binding er implementert.
- Slutten av kroppen til hovedfunksjonen ().
Kompileringstidspolymorfisme vs. Run-Time polymorfisme
Her er de største forskjellene mellom de to:
Kompileringstid polymorfisme | Kjøretids polymorfisme |
Det kalles også tidlig binding eller statisk polymorfisme | Det kalles også sen / dynamisk binding eller dynamisk polymorfisme |
Metoden kalles / påkalles i løpet av kompileringstiden | Metoden kalles / påberopes i løpetid |
Implementert via funksjonsoverbelastning og operatøroverbelastning | Implementert via metodeoverstyring og virtuelle funksjoner |
Eksempel på metodeoverbelastning. Mange metoder kan ha lignende navn, men forskjellige antall eller typer argumenter | Eksempel, metodeoverstyring. Mange metoder kan ha et lignende navn og samme prototype. |
Raskere utførelse siden metodene er funnet i løpet av kompileringstiden | Langsommere utførelse siden metodeoppdageren gjøres i løpet av kjøretiden. |
Mindre fleksibilitet for problemløsning er gitt siden alt er kjent i løpet av kompileringstiden. | Mye fleksibilitet er gitt for å løse komplekse problemer siden metoder blir oppdaget i løpet av kjøretiden. |
Sammendrag:
- Polymorfisme betyr å ha mange former.
- Det oppstår når det er et hierarki av klasser relatert gjennom arv.
- Med polymorfisme kan en funksjon oppføre seg annerledes basert på objektet som påkaller / kaller det.
- I kompileringstidspolymorfisme etableres funksjonen som skal påberopes under kompileringstid.
- I løpetidspolymorfisme etableres funksjonen som skal påberopes under kjøretid.
- Kompileringstidspolymorfisme bestemmes gjennom funksjonsoverbelastning og operatøroverbelastning.
- I funksjonsoverbelastning er det mange funksjoner med lignende navn, men forskjellige argumenter.
- Parametrene kan variere i antall eller type.
- I operatøroverbelastning defineres en ny betydning for C ++ -operatører.
- Runtime polymorfisme oppnås gjennom funksjonsoverstyring.
- I funksjonsoverstyring gir en avledet klasse en ny definisjon til en funksjon definert i basisklassen.