C++ Polymorfi med eksempel

Hvad er polymorfisme i C++?

In C++, får polymorfi en medlemsfunktion til at opføre sig anderledes baseret på det objekt, der kalder/kalder den. Polymorfi er et græsk ord, der betyder at have mange former. Det opstår, når du har et hierarki af klasser relateret gennem arv.

Antag for eksempel, at vi har funktionen makeSound(). Når en kat kalder denne funktion, vil den frembringe miav-lyden. Når en ko aktiverer den samme funktion, vil den give moow-lyden.

Polymorfi i C++

Selvom vi har én funktion, opfører den sig anderledes under forskellige omstændigheder. Funktionen har mange former; derfor har vi opnået polymorfi.

Typer af polymorfisme

C++ understøtter to typer polymorfi:

  • Kompileringstidspolymorfi, og
  • Runtime polymorfi.

Typer af polymorfisme

Kompiler tidspolymorfi

Du påberåber de overbelastede funktioner ved at matche antallet og typen af ​​argumenter. Oplysningerne er til stede under kompileringstiden. Dette betyder C++ compiler vil vælge den rigtige funktion på kompileringstidspunktet.

Kompileringstidspolymorfi opnås gennem funktionsoverbelastning og operatøroverbelastning.

Funktion Overbelastning

Funktionsoverbelastning opstår, når vi har mange funktioner med lignende navne, men forskellige argumenter. Argumenterne kan variere med hensyn til antal eller type.

Eksempel 1

#include <iostream> 
using 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;
}

Output:

Funktion Overbelastning

Her er et skærmbillede af koden:

Funktion Overbelastning

Kodeforklaring:

  1. Inkluder iostream-header-filen i vores kode. Vi vil være i stand til at bruge dens funktioner.
  2. Inkluder std-navneområdet i vores kode. Vi vil være i stand til at bruge dets klasser uden at kalde det.
  3. Opret en funktion med navnet test, der tager en heltalsparameter i. { markerer begyndelsen på kroppen af ​​funktionstesten.
  4. Erklæring, der skal udføres, hvis ovenstående funktionstest påkaldes/kaldes.
  5. Slut på hoveddelen af ​​ovenstående funktionstest.
  6. Opret en funktion med navnet test, der tager en flydende parameter f. { markerer begyndelsen på kroppen af ​​funktionstesten.
  7. Erklæring, der skal udføres, hvis ovenstående funktionstest påkaldes/kaldes.
  8. Slutningen af ​​kroppen af ​​ovenstående funktionstest.
  9. Opret en funktion med navnet test, der tager en karakterparameter ch. { markerer begyndelsen på kroppen af ​​funktionstesten.
  10. Erklæring, der skal udføres, hvis ovenstående funktionstest påkaldes/kaldes.
  11. Slutningen af ​​kroppen af ​​ovenstående funktionstest.
  12. Kald funktionen main(). { markerer begyndelsen af ​​funktionens brødtekst.
  13. Kald funktionstesten og send 5 til den som værdien af ​​argumentet. Dette påkalder testfunktionen, der accepterer et heltalsargument, det vil sige den første testfunktion.
  14. Kald funktionstesten og send 5.5 til den som værdien af ​​argumentet. Dette vil påkalde testfunktionen, der accepterer et float-argument, det vil sige den anden testfunktion.
  15. Kald funktionstesten og send fem til den som værdien af ​​argumentet. Dette vil påkalde testfunktionen, der accepterer et karakterargument, det vil sige den tredje testfunktion.
  16. Programmet skal returnere en værdi, hvis det kører.
  17. Slutningen af ​​hoveddelen af ​​hoved()-funktionen.

Vi har tre funktioner med samme navn, men forskellige typer argumenter. Vi har opnået polymorfi.

Operator overbelastning

In Operator Overbelastning definerer vi en ny betydning for en C++ operatør. Det ændrer også, hvordan operatøren arbejder. For eksempel kan vi definere + operatoren til at sammenkæde to strenge. Vi kender det som additionsoperatoren til at tilføje numeriske værdier. Efter vores definition, når den placeres mellem heltal, vil den tilføje dem. Når den placeres mellem strenge, vil den sammenkæde dem.

Eksempel 2

#include<iostream> 
using 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();
}

Output:

Operator overbelastning

Her er et skærmbillede af koden:

Operator overbelastning

Operator overbelastning

Kodeforklaring:

  1. Inkluder iostream-header-filen i vores program for at bruge dens funktioner.
  2. Inkluder std-navneområdet i vores program for at bruge dets klasser uden at kalde det.
  3. Opret en klasse ved navn ComplexNum. { markerer begyndelsen af ​​klassens brødtekst.
  4. Brug den private adgangsmodifikator til at markere variabler som private, hvilket betyder, at de kun kan tilgås fra klassen.
  5. Definer to heltalsvariabler, reelle og over.
  6. Brug offentlig adgangsmodifikator til at markere konstruktøren som offentlig, hvilket betyder, at den vil være tilgængelig selv uden for klasse.
  7. Opret klassekonstruktøren og initialiser variablerne.
  8. Initialiser værdien af ​​variablen reelle.
  9. Initialiser værdien af ​​variablen over.
  10. Slut på konstruktørlegemet.
  11. Vi skal tilsidesætte betydningen af ​​+-operatoren.
  12. Opret datatyperesultatet af typen ComplexNum.
  13. Brug operatoren + med komplekse tal. Denne linje tilføjer den reelle del af et tal til den reelle del af et andet tal.
  14. Brug operatoren + med komplekse tal. Denne linje tilføjer den imaginære del af et tal til den imaginære del af et andet tal.
  15. Programmet returnerer værdien af ​​det variable resultat ved vellykket udførelse.
  16. Slutningen af ​​definitionen af ​​den nye betydning af + operator, det vil sige overbelastning.
  17. Kald print() metoden.
  18. Udskriv det nye komplekse tal efter tilføjelse på konsollen.
  19. Slutningen af ​​body of print()-funktionen.
  20. Slutningen af ​​brødteksten af ​​ComplexNum-klassen.
  21. Kald funktionen main().
  22. Send værdierne af både reelle og komplekse dele, der skal tilføjes. Den første del af c1 vil blive tilføjet til den første del af c2, det vil sige 10+3. Den anden del af c1 vil blive tilføjet den anden del af c, det vil sige 2+7.
  23. Udfør en operation ved at bruge operatoren overbelastet + og gem resultatet i variabel c3.
  24. Udskriv værdien af ​​variabel c3 på konsollen.
  25. Slutningen af ​​hoveddelen af ​​funktionen main().

Runtime polymorfisme

Dette sker, når et objekts metode påkaldes/kaldes under kørsel i stedet for under kompilering. Runtime polymorfi opnås gennem funktionstilsidesættelse. Funktionen, der skal kaldes/kaldes, etableres under kørsel.

Funktion tilsidesætte

Funktionstilsidesættelse sker, når en funktion af basisklassen får en ny definition i en afledt klasse. På det tidspunkt kan vi sige, at basisfunktionen er blevet tilsidesat.

For eksempel:

#include <iostream>
using 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;

}

Output:

Funktion tilsidesætte

Her er et skærmbillede af koden:

Funktion tilsidesætte

Kodeforklaring:

  1. Importer iostream header-filen til vores program for at bruge dens funktioner.
  2. Inkluder std-navneområdet i vores program for at bruge dets klasser uden at kalde det.
  3. Opret en klasse ved navn Pattedyr. { markerer begyndelsen af ​​klassens brødtekst.
  4. Brug public access modifier til at indstille den funktion, vi er ved at oprette, som offentligt tilgængelig. Det vil være tilgængeligt uden for denne klasse.
  5. Opret en offentlig funktion ved navn eat. { markerer begyndelsen af ​​funktionslegemet.
  6. Udskriv sætningen tilføjet til cout-funktionen, når funktionen eat() aktiveres.
  7. Slutningen af ​​kroppen af ​​funktion spise().
  8. Slutningen af ​​kroppen af ​​klassen Pattedyr.
  9. Opret en klasse ved navn Ko, der arver Pattedyr-klassen. Ko er den afledte klasse, mens pattedyr er basisklassen. { markerer begyndelsen af ​​denne klasse.
  10. Brug public access modifier til at markere den funktion, vi er ved at oprette, som offentligt tilgængelig. Det vil være tilgængeligt uden for denne klasse.
  11. Tilsidesæt funktionen eat(), der blev defineret i basisklassen. { markerer begyndelsen af ​​funktionslegemet.
  12. Den erklæring, der skal udskrives på konsollen, når denne funktion aktiveres.
  13. Slutningen af ​​kroppen af ​​funktionen eat().
  14. Slutningen af ​​kroppen af ​​klassen Ko.
  15. Kald funktionen main(). { markerer begyndelsen af ​​denne funktions brødtekst.
  16. Opret en instans af Cow-klassen og giv den navnet c.
  17. Kald funktionen eat() defineret i Cow-klassen.
  18. Programmet skal returnere en værdi efter vellykket afslutning.
  19. Slut på main()-funktionen.

C++ Virtuel funktion

En virtuel funktion er en anden måde at implementere run-time polymorfi i C++. Det er en speciel funktion defineret i en basisklasse og omdefineret i den afledte klasse. For at erklære en virtuel funktion skal du bruge det virtuelle nøgleord. Nøgleordet skal gå forud for erklæringen af ​​funktionen i basisklassen.

Hvis en virtuel funktionsklasse nedarves, omdefinerer den virtuelle funktion den virtuelle funktion, så den passer til dens behov. For eksempel:

#include <iostream>  
using 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();      
	}

Output:

C++ Virtuel funktion

Her er et skærmbillede af koden:

C++ Virtuel funktion

Kodeforklaring:

  1. Inkluder iostream-headerfilen i koden for at bruge dens funktioner.
  2. Inkluder std-navneområdet i vores kode for at bruge dets klasser uden at kalde det.
  3. Opret en klasse ved navn ClassA.
  4. Brug offentlig adgangsmodifikator til at markere et klassemedlem som offentligt tilgængeligt.
  5. Opret en virtuel funktion ved navn show(). Det bliver en offentlig funktion.
  6. Teksten, der skal udskrives, når den fremkaldte show() påkaldes. Endl er en C++ søgeord, hvilket betyder slutlinje. Det flytter musemarkøren til næste linje.
  7. Slutningen af ​​kroppen af ​​den virtuelle funktion show().
  8. Slutningen af ​​kroppen af ​​klassen KlasseA.
  9. Oprettelse af en ny klasse ved navn ClassB, der arver klassen ClassA. KlasseA bliver basisklassen, mens KlasseB bliver den afledte klasse.
  10. Brug offentlig adgangsmodifikator til at markere et klassemedlem som offentligt tilgængeligt.
  11. Omdefiner den virtuelle funktion show() afledt i basisklassen.
  12. Teksten, der skal udskrives på konsollen, når funktionen show() defineret i den afledte klasse aktiveres.
  13. Slut på brødteksten af ​​show()-funktionen.
  14. Slutningen af ​​kroppen af ​​den afledte klasse, KlasseB.
  15. Kald funktionen main(). Programlogikken skal tilføjes i dens krop.
  16. Opret en pointervariabel ved navn a. Det peger på klassen ved navn ClassA.
  17. Opret en forekomst af klassen ved navn ClassB. Forekomsten får navnet b.
  18. Tildel værdierne lagre i adressen b i variablen a.
  19. Kald funktionen show() defineret i den afledte klasse. Sen binding er implementeret.
  20. Slutningen af ​​hoveddelen af ​​funktionen main().

Kompileringstidspolymorfi vs. Run-Time Polymorfisme

Her er de største forskelle mellem de to:

Kompileringstid polymorfisme Run-time polymorfi
Det kaldes også tidlig binding eller statisk polymorfi Det kaldes også sen/dynamisk binding eller dynamisk polymorfi
Metoden kaldes/påkaldes i kompileringstiden Metoden kaldes/påkaldes under kørselstid
Implementeret via funktionsoverbelastning og operatøroverbelastning Implementeret via metodeoverstyring og virtuelle funktioner
Eksempel, metodeoverbelastning. Mange metoder kan have lignende navne, men forskellige antal eller typer argumenter Eksempel, metode tilsidesættelse. Mange metoder kan have et lignende navn og den samme prototype.
Hurtigere udførelse, da metodeopdagelsen udføres i kompileringstiden Langsommere udførelse, da metodeopdager udføres under kørsel.
Less fleksibilitet til problemløsning er givet, da alt er kendt i kompileringstiden. Der er givet megen fleksibilitet til at løse komplekse problemer, da metoder opdages under kørsel.

Resumé

  • Polymorfi betyder at have mange former.
  • Det opstår, når der er et hierarki af klasser relateret gennem arv.
  • Med polymorfi kan en funktion opføre sig anderledes baseret på det objekt, der påkalder/kalder den.
  • I kompileringstidspolymorfi etableres den funktion, der skal påberåbes, under kompileringstiden.
  • I runtime-polymorfi etableres den funktion, der skal aktiveres, under runtime.
  • Kompileringstidspolymorfi bestemmes gennem funktionsoverbelastning og operatøroverbelastning.
  • Ved funktionsoverbelastning er der mange funktioner med lignende navne, men forskellige argumenter.
  • Parametrene kan variere i antal eller type.
  • Ved operatøroverbelastning defineres en ny betydning for C++ Operatører.
  • Runtime polymorfi opnås gennem funktionstilsidesættelse.
  • Ved funktionstilsidesættelse giver en afledt klasse en ny definition til en funktion defineret i basisklassen.