Wat is polymorfisme in C ++?
In C ++ zorgt polymorfisme ervoor dat een lidfunctie zich anders gedraagt op basis van het object dat het aanroept / aanroept. Polymorfisme is een Grieks woord dat vele vormen betekent. Het treedt op wanneer u een hiërarchie van klassen hebt die zijn gerelateerd door overerving.
Stel dat we de functie makeSound () hebben. Wanneer een kat deze functie aanroept, produceert hij het miauwgeluid. Wanneer een koe dezelfde functie oproept, zal deze het moow-geluid geven.
Hoewel we één functie hebben, gedraagt deze zich onder verschillende omstandigheden anders. De functie kent vele vormen; vandaar dat we polymorfisme hebben bereikt.
In deze C ++ tutorial leer je:
- Wat is polymorfisme?
- Soorten polymorfisme
- Compile Time Polymorphism
- Functie overbelasting
- Overbelasting door operator
- Runtime polymorfisme
- Functie overschrijven
- C ++ virtuele functie
- Compile-Time Polymorphism Vs. Runtime polymorfisme
Soorten polymorfisme
C ++ ondersteunt twee soorten polymorfisme:
- Compilatietijd polymorfisme, en
- Runtime polymorfisme.
Compile Time Polymorphism
U roept de overbelaste functies op door het aantal en het type argumenten te matchen. De informatie is aanwezig tijdens het compileren. Dit betekent dat de C ++ - compiler de juiste functie selecteert tijdens het compileren.
Compilatietijd polymorfisme wordt bereikt door overbelasting van functies en overbelasting van operators.
Functie overbelasting
Overbelasting van functies treedt op als we veel functies hebben met vergelijkbare namen maar met verschillende argumenten. De argumenten kunnen verschillen in aantal of type.
Voorbeeld 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;}
Uitgang:
Hier is een screenshot van de code:
Code Verklaring:
- Voeg het iostream-headerbestand toe aan onze code. We zullen de functies ervan kunnen gebruiken.
- Neem de std-naamruimte op in onze code. We zullen zijn klassen kunnen gebruiken zonder het op te roepen.
- Maak een functie met de naam test waaraan een integer-parameter i moet doorgegeven worden. De {markeert het begin van de functietest.
- Verklaring die moet worden uitgevoerd als de bovenstaande functietest wordt aangeroepen / aangeroepen.
- Einde van de bovenstaande functietest.
- Maak een functie met de naam test waaraan een float-parameter f moet doorgegeven worden. De {markeert het begin van de functietest.
- Verklaring die moet worden uitgevoerd als de bovenstaande functietest wordt aangeroepen / aangeroepen.
- Einde van de hoofdtekst van de bovenstaande functietest.
- Maak een functie met de naam test waaraan een karakterparameter ch moet doorgegeven worden. De {markeert het begin van de functietest.
- Verklaring die moet worden uitgevoerd als de bovenstaande functietest wordt aangeroepen / aangeroepen.
- Einde van de hoofdtekst van de bovenstaande functietest.
- Roep de functie main () aan. De {markeert het begin van de hoofdtekst van de functie.
- Roep de functietest aan en geef er 5 aan door als de waarde van het argument. Dit roept de testfunctie op die een integer-argument accepteert, dat wil zeggen, de eerste testfunctie.
- Roep de functietest aan en geef er 5.5 aan als de waarde van het argument. Hierdoor wordt de testfunctie aangeroepen die een float-argument accepteert, dat wil zeggen de tweede testfunctie.
- Roep de functietest aan en geef er vijf door als de waarde van het argument. Hierdoor wordt de testfunctie aangeroepen die een tekenargument accepteert, dat wil zeggen de derde testfunctie.
- Het programma moet een waarde retourneren als het met succes wordt uitgevoerd.
- Het einde van de hoofdtekst van de functie main ().
We hebben drie functies met dezelfde naam maar met verschillende soorten argumenten. We hebben polymorfisme bereikt.
Overbelasting door operator
In Operator Overloading definiëren we een nieuwe betekenis voor een C ++ operator. Het verandert ook hoe de operator werkt. We kunnen bijvoorbeeld de operator + definiëren om twee strings samen te voegen. We kennen het als de opteloperator voor het toevoegen van numerieke waarden. Na onze definitie, wanneer geplaatst tussen gehele getallen, worden ze toegevoegd. Wanneer ze tussen strings worden geplaatst, worden ze aaneengeschakeld.
Voorbeeld 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();}
Uitgang:
Hier is een screenshot van de code:
Code Verklaring:
- Neem het iostream-headerbestand op in ons programma om de functies ervan te gebruiken.
- Neem de std-naamruimte op in ons programma om zijn klassen te gebruiken zonder het aan te roepen.
- Maak een klasse met de naam ComplexNum. De {markeert het begin van de hoofdtekst van de klas.
- Gebruik de privétoegangsmodificator om variabelen als privé te markeren, wat betekent dat ze alleen toegankelijk zijn vanuit de klas.
- Definieer twee integer-variabelen, reëel en hoger.
- Gebruik de modifier voor openbare toegang om de constructor als openbaar te markeren, wat betekent dat deze zelfs van buiten de klas toegankelijk zal zijn.
- Maak de klassenconstructor en initialiseer de variabelen.
- Initialiseer de waarde van de variabele real.
- Initialiseer de waarde van de variabele over.
- Einde van de constructorbody.
- We moeten de betekenis van de + operator overschrijven.
- Maak het resultaat van het gegevenstype van het type ComplexNum.
- Gebruik de operator + bij complexe getallen. Deze regel voegt het reële deel van een getal toe aan het reële gedeelte van een ander getal.
- Gebruik de operator + bij complexe getallen. Deze regel voegt het imaginaire deel van een getal toe aan het imaginaire gedeelte van een ander getal.
- Het programma retourneert de waarde van het variabele resultaat na succesvolle uitvoering.
- Einde van de definitie van de nieuwe betekenis van operator +, dat wil zeggen overbelasting.
- Roep de methode print () aan.
- Druk het nieuwe complexe nummer af na toevoeging op de console.
- Einde van de body of print () functie.
- Einde van de hoofdtekst van de klasse ComplexNum.
- Roep de functie main () aan.
- Geef de waarden door van zowel echte als complexe onderdelen die moeten worden toegevoegd. Het eerste deel van c1 wordt toegevoegd aan het eerste deel van c2, dat wil zeggen 10 + 3. Het tweede deel van c1 wordt toegevoegd aan het tweede deel van c, dat wil zeggen 2 + 7.
- Voer een bewerking uit met de operator overloaded + en sla het resultaat op in variabele c3.
- Druk de waarde van variabele c3 af op de console.
- Einde van de hoofdtekst van de functie main ().
Runtime polymorfisme
Dit gebeurt wanneer de methode van een object wordt aangeroepen / aangeroepen tijdens runtime in plaats van tijdens het compileren. Runtime-polymorfisme wordt bereikt door het overschrijven van functies. De functie die moet worden aangeroepen / aangeroepen, wordt tot stand gebracht tijdens runtime.
Functie overschrijven
Functie-overschrijving vindt plaats wanneer een functie van de basisklasse een nieuwe definitie krijgt in een afgeleide klasse. Op dat moment kunnen we zeggen dat de basisfunctie is overschreven.
Bijvoorbeeld:
#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;}
Uitgang:
Hier is een screenshot van de code:
Code Verklaring:
- Importeer het iostream-headerbestand in ons programma om de functies ervan te gebruiken.
- Neem de std-naamruimte op in ons programma om zijn klassen te gebruiken zonder het aan te roepen.
- Maak een klasse met de naam Mammal. De {markeert het begin van de hoofdtekst van de klas.
- Gebruik de modificator voor openbare toegang om de functie die we gaan maken in te stellen als openbaar toegankelijk. Het zal van buiten deze klas toegankelijk zijn.
- Maak een openbare functie met de naam eat. De {markeert het begin van de hoofdtekst van de functie.
- Druk de instructie af die aan de cout-functie is toegevoegd wanneer de functie eat () wordt aangeroepen.
- Het einde van het functioneel lichaam eat ().
- Einde van het lichaam van de klasse Zoogdier.
- Maak een klasse met de naam Cow die de klasse Mammal erft. Koe is de afgeleide klasse, terwijl Mammal de basisklasse is. De {markeert het begin van deze les.
- Gebruik de modificator voor openbare toegang om de functie die we gaan maken als openbaar toegankelijk te markeren. Het zal van buiten deze klas toegankelijk zijn.
- Overschrijf de functie eat () die is gedefinieerd in de basisklasse. De {markeert het begin van de hoofdtekst van de functie.
- De instructie die op de console moet worden afgedrukt wanneer deze functie wordt aangeroepen.
- Einde van het lichaam van de functie eat ().
- Einde van het lichaam van de klas Koe.
- Roep de functie main () aan. De {markeert het begin van de hoofdtekst van deze functie.
- Maak een instantie van de klasse Cow en geef deze de naam c.
- Roep de functie eat () aan die is gedefinieerd in de klasse Koe.
- Het programma moet een waarde retourneren bij succesvolle voltooiing.
- Einde van de main () functie.
C ++ virtuele functie
Een virtuele functie is een andere manier om runtime-polymorfisme in C ++ te implementeren. Het is een speciale functie gedefinieerd in een basisklasse en opnieuw gedefinieerd in de afgeleide klasse. Om een virtuele functie te declareren, moet u het virtuele sleutelwoord gebruiken. Het sleutelwoord moet voorafgaan aan de declaratie van de functie in de basisklasse.
Als een virtuele functieklasse wordt overgeërfd, herdefinieert de virtuele klasse de virtuele functie om aan zijn behoeften te voldoen. Bijvoorbeeld:
#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();}
Uitgang:
Hier is een screenshot van de code:
Code Verklaring:
- Neem het iostream-headerbestand op in de code om de functies ervan te gebruiken.
- Neem de std-naamruimte op in onze code om de klassen ervan te gebruiken zonder deze aan te roepen.
- Maak een klasse met de naam ClassA.
- Gebruik de modifier voor openbare toegang om een klaslid als openbaar toegankelijk te markeren.
- Maak een virtuele functie met de naam show (). Het zal een publieke functie zijn.
- De tekst die moet worden afgedrukt wanneer de show () wordt aangeroepen, wordt aangeroepen. De endl is een C ++ -woord, wat eindregel betekent. Het verplaatst de muiscursor naar de volgende regel.
- Einde van de body van de virtuele functie show ().
- Einde van het lichaam van de klasse ClassA.
- Een nieuwe klasse maken met de naam ClassB die de klasse ClassA erft. ClassA wordt de basisklasse, terwijl ClassB de afgeleide klasse wordt.
- Gebruik de modifier voor openbare toegang om een klaslid als openbaar toegankelijk te markeren.
- Herdefinieer de virtuele functie show () die is afgeleid in de basisklasse.
- De tekst die op de console moet worden afgedrukt wanneer de functie show () die is gedefinieerd in de afgeleide klasse, wordt aangeroepen.
- Einde van de hoofdtekst van de functie show ().
- Einde van de hoofdtekst van de afgeleide klasse, ClassB.
- Roep de functie main () aan. De programmalogica moet in zijn lichaam worden toegevoegd.
- Maak een pointervariabele met de naam a. Het verwijst naar de klasse met de naam ClassA.
- Maak een instantie van de klasse met de naam ClassB. De instantie krijgt de naam b.
- Wijs de waardenopslag in het adres b in de variabele a toe.
- Roep de functie show () aan die is gedefinieerd in de afgeleide klasse. Late binding is geïmplementeerd.
- Einde van de hoofdtekst van de functie main ().
Compile-Time Polymorphism Vs. Runtime polymorfisme
Dit zijn de belangrijkste verschillen tussen de twee:
Compilatietijd polymorfisme | Runtime polymorfisme |
Het wordt ook vroeg bindend of statisch polymorfisme genoemd | Het wordt ook wel late / dynamische binding of dynamisch polymorfisme genoemd |
De methode wordt aangeroepen / aangeroepen tijdens het compileren | De methode wordt aangeroepen / aangeroepen tijdens runtime |
Geïmplementeerd via functie overbelasting en overbelasting van de operator | Geïmplementeerd via methode-overschrijving en virtuele functies |
Voorbeeld methode overbelasting. Veel methoden kunnen vergelijkbare namen hebben, maar een ander aantal of typen argumenten | Voorbeeld: methode overschrijven. Veel methoden hebben mogelijk een vergelijkbare naam en hetzelfde prototype. |
Snellere uitvoering omdat de methoden worden ontdekt tijdens het compileren | Langzamere uitvoering sinds methode-ontdekker wordt uitgevoerd tijdens runtime. |
Er wordt minder flexibiliteit geboden voor het oplossen van problemen, aangezien alles bekend is tijdens het compileren. | Er wordt veel flexibiliteit geboden voor het oplossen van complexe problemen, aangezien methoden worden ontdekt tijdens runtime. |
Overzicht:
- Polymorfisme betekent vele vormen hebben.
- Het treedt op als er een hiërarchie van klassen is die door overerving met elkaar zijn verbonden.
- Met polymorfisme kan een functie zich anders gedragen op basis van het object dat het aanroept / aanroept.
- Bij polymorfisme tijdens het compileren wordt de aan te roepen functie vastgesteld tijdens het compileren.
- In runtime-polymorfisme wordt de aan te roepen functie tijdens runtime vastgesteld.
- Compilatietijd polymorfisme wordt bepaald door overbelasting van functies en overbelasting van operators.
- Bij functie-overbelasting zijn er veel functies met vergelijkbare namen maar met verschillende argumenten.
- De parameters kunnen verschillen in aantal of type.
- Bij overbelasting van operators wordt een nieuwe betekenis gedefinieerd voor C ++ operators.
- Runtime-polymorfisme wordt bereikt door het overschrijven van functies.
- Bij het overschrijven van functies geeft een afgeleide klasse een nieuwe definitie aan een functie die is gedefinieerd in de basisklasse.