C++ Polymorphismus mit Beispiel
Was ist Polymorphismus in C++?
In C++, Polymorphismus bewirkt, dass sich eine Mitgliedsfunktion je nach dem Objekt, das sie aufruft, unterschiedlich verhรคlt. Polymorphismus ist ein griechisches Wort, das โviele Formen habenโ bedeutet. Er tritt auf, wenn Sie eine Hierarchie von Klassen haben, die durch Vererbung miteinander verbunden sind.
Angenommen, wir haben die Funktion makeSound(). Wenn eine Katze diese Funktion aufruft, erzeugt sie ein Miaugerรคusch. Wenn eine Kuh dieselbe Funktion aufruft, gibt sie das Mรคhgerรคusch von sich.
Obwohl wir eine Funktion haben, verhรคlt sie sich unter verschiedenen Umstรคnden unterschiedlich. Die Funktion hat viele Formen; daher haben wir Polymorphismus erreicht.
Arten des Polymorphismus
C++ unterstรผtzt zwei Arten von Polymorphismus:
- Polymorphismus zur Kompilierungszeit und
- Laufzeitpolymorphismus.
Kompilierzeitpolymorphismus
Sie rufen die รผberladenen Funktionen auf, indem Sie die Anzahl und den Typ der Argumente abgleichen. Die Informationen sind wรคhrend der Kompilierungszeit vorhanden. Das bedeutet, dass die C++ Der Compiler wรคhlt zur Kompilierzeit die richtige Funktion aus.
Polymorphismus zur Kompilierungszeit wird durch Funktions- und Operatorรผberladung erreicht.
Funktionsรผberlastung
Eine Funktionsรผberladung tritt auf, wenn wir viele Funktionen mit รคhnlichen Namen, aber unterschiedlichen Argumenten haben. Die Argumente kรถnnen sich hinsichtlich der Anzahl oder Art unterscheiden.
Beispiel 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;
}
Ausgang:
Hier ist ein Screenshot des Codes:
Code Erlรคuterung:
- Fรผgen Sie die iostream-Header-Datei in unseren Code ein. Wir werden seine Funktionen nutzen kรถnnen.
- Fรผgen Sie den std-Namespace in unseren Code ein. Wir kรถnnen seine Klassen verwenden, ohne es aufzurufen.
- Erstellen Sie eine Funktion namens test, die einen ganzzahligen Parameter i akzeptiert. Das { markiert den Anfang des Hauptteils des Funktionstests.
- Anweisung, die ausgefรผhrt werden soll, wenn der obige Funktionstest aufgerufen/aufgerufen wird.
- Ende des Hauptteils des obigen Funktionstests.
- Erstellen Sie eine Funktion namens test, die einen Float-Parameter f akzeptiert. Das { markiert den Anfang des Hauptteils des Funktionstests.
- Anweisung, die ausgefรผhrt werden soll, wenn der obige Funktionstest aufgerufen/aufgerufen wird.
- Ende des Hauptteils des obigen Funktionstests.
- Erstellen Sie eine Funktion namens test, die einen Zeichenparameter ch akzeptiert. Das { markiert den Anfang des Hauptteils des Funktionstests.
- Anweisung, die ausgefรผhrt werden soll, wenn der obige Funktionstest aufgerufen/aufgerufen wird.
- Ende des Hauptteils des obigen Funktionstests.
- Rufen Sie die Funktion main() auf. Das { markiert den Anfang des Funktionskรถrpers.
- Rufen Sie den Funktionstest auf und รผbergeben Sie ihm 5 als Wert des Arguments. Dadurch wird die Testfunktion aufgerufen, die ein ganzzahliges Argument akzeptiert, also die erste Testfunktion.
- Rufen Sie den Funktionstest auf und รผbergeben Sie ihm 5.5 als Wert des Arguments. Dadurch wird die Testfunktion aufgerufen, die ein Float-Argument akzeptiert, also die zweite Testfunktion.
- Rufen Sie die Funktion test auf und รผbergeben Sie ihr fรผnf als Wert des Arguments. Dadurch wird die Testfunktion aufgerufen, die ein Zeichenargument akzeptiert, also die dritte Testfunktion.
- Das Programm muss einen Wert zurรผckgeben, wenn es erfolgreich ausgefรผhrt wird.
- Das Ende des Hauptteils der main()-Funktion.
Wir haben drei Funktionen mit demselben Namen, aber unterschiedlichen Argumenttypen. Wir haben Polymorphismus erreicht.
Operator รberlastung
In Operator Overloading definieren wir eine neue Bedeutung fรผr eine C++ Operator. Es รคndert auch die Funktionsweise des Operators. Beispielsweise kรถnnen wir den Operator + definieren, um zwei Zeichenfolgen zu verketten. Wir kennen ihn als Additionsoperator zum Addieren numerischer Werte. Nach unserer Definition wird er diese addieren, wenn er zwischen Ganzzahlen steht. Wenn er zwischen Zeichenfolgen steht, wird er diese verketten.
Beispiel 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();
}
Ausgang:
Hier ist ein Screenshot des Codes:
Code Erlรคuterung:
- Binden Sie die iostream-Header-Datei in unser Programm ein, um dessen Funktionen nutzen zu kรถnnen.
- Fรผgen Sie den std-Namespace in unser Programm ein, um seine Klassen zu verwenden, ohne ihn aufzurufen.
- Erstellen Sie eine Klasse mit dem Namen ComplexNum. Die { markiert den Anfang des Klassenkรถrpers.
- Verwenden Sie den Zugriffsmodifikator โprivateโ, um Variablen als privat zu markieren, was bedeutet, dass auf sie nur innerhalb der Klasse zugegriffen werden kann.
- Definieren Sie zwei ganzzahlige Variablen, reell und รผber.
- Verwenden Sie den Zugriffsmodifikator public, um den Konstruktor als รถffentlich zu markieren, was bedeutet, dass er auch von auรerhalb zugรคnglich ist Klasse.
- Erstellen Sie den Klassenkonstruktor und initialisieren Sie die Variablen.
- Initialisieren Sie den Wert der Variablen real.
- Initialisieren Sie den Wert der Variablen รผber.
- Ende des Konstruktorkรถrpers.
- Wir mรผssen die Bedeutung des +-Operators รผberschreiben.
- Erstellen Sie den Datentyp โErgebnisโ vom Typ โComplexNumโ.
- Verwenden Sie den Operator + mit komplexen Zahlen. Diese Zeile addiert den Realteil einer Zahl zum Realteil einer anderen Zahl.
- Verwenden Sie den Operator + mit komplexen Zahlen. Diese Zeile addiert den Imaginรคrteil einer Zahl zum Imaginรคrteil einer anderen Zahl.
- Bei erfolgreicher Ausfรผhrung gibt das Programm den Wert der Variablen result zurรผck.
- Ende der Definition der neuen Bedeutung des +-Operators, d. h. รberladung.
- Rufen Sie die print()-Methode auf.
- Drucken Sie die neue komplexe Zahl nach der Addition auf der Konsole.
- Ende des Hauptteils der print()-Funktion.
- Ende des Hauptteils der ComplexNum-Klasse.
- Rufen Sie die Funktion main() auf.
- รbergeben Sie die Werte der zu addierenden reellen und komplexen Teile. Der erste Teil von c1 wird zum ersten Teil von c2 addiert, also 10+3. Der zweite Teil von c1 wird zum zweiten Teil von c addiert, also 2+7.
- Fรผhren Sie eine Operation mit dem รผberladenen +-Operator aus und speichern Sie das Ergebnis in der Variablen c3.
- Geben Sie den Wert der Variablen c3 auf der Konsole aus.
- Ende des Hauptteils der Funktion main().
Laufzeitpolymorphismus
Dies geschieht, wenn die Methode eines Objekts zur Laufzeit und nicht zur Kompilierungszeit aufgerufen/aufgerufen wird. Laufzeitpolymorphismus wird durch Funktionsรผberschreibung erreicht. Die aufzurufende/aufzurufende Funktion wird zur Laufzeit festgelegt.
Funktion รผberschreiben
Funktionsรผberschreibungen treten auf, wenn einer Funktion der Basisklasse eine neue Definition in einer abgeleiteten Klasse gegeben wird. Zu diesem Zeitpunkt kรถnnen wir sagen, dass die Basisfunktion รผberschrieben wurde.
Beispielsweise:
#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;
}
Ausgang:
Hier ist ein Screenshot des Codes:
Code Erlรคuterung:
- Importieren Sie die iostream-Header-Datei in unser Programm, um dessen Funktionen zu nutzen.
- Fรผgen Sie den std-Namespace in unser Programm ein, um seine Klassen zu verwenden, ohne ihn aufzurufen.
- Erstellen Sie eine Klasse mit dem Namen Mammal. Das { markiert den Anfang des Klassenkรถrpers.
- Verwenden Sie den Modifikator fรผr den รถffentlichen Zugriff, um die Funktion, die wir erstellen mรถchten, als รถffentlich zugรคnglich festzulegen. Es wird von auรerhalb dieser Klasse zugรคnglich sein.
- Erstellen Sie eine รถffentliche Funktion namens eat. Das { markiert den Anfang des Funktionskรถrpers.
- Gibt die der cout-Funktion hinzugefรผgte Anweisung aus, wenn die Funktion eat() aufgerufen wird.
- Das Ende des Funktionskรถrpers eat().
- Ende des Hauptteils der Klasse Sรคugetier.
- Erstellen Sie eine Klasse mit dem Namen Cow, die die Mammal-Klasse erbt. Cow ist die abgeleitete Klasse, wรคhrend Mammal die Basisklasse ist. Das { markiert den Anfang dieser Klasse.
- Verwenden Sie den Modifikator โpublic accessโ, um die Funktion, die wir erstellen mรถchten, als รถffentlich zugรคnglich zu markieren. Es wird von auรerhalb dieser Klasse zugรคnglich sein.
- รberschreiben Sie die Funktion eat(), die in der Basisklasse definiert wurde. Das { markiert den Anfang des Funktionskรถrpers.
- Die Anweisung, die beim Aufruf dieser Funktion auf der Konsole ausgegeben werden soll.
- Ende des Hauptteils der Funktion eat().
- Ende des Rumpfes der Klasse Cow.
- Rufen Sie die Funktion main() auf. Das { markiert den Anfang des Hauptteils dieser Funktion.
- Erstellen Sie eine Instanz der Cow-Klasse und geben Sie ihr den Namen c.
- Rufen Sie die in der Cow-Klasse definierte Funktion eat() auf.
- Das Programm muss bei erfolgreichem Abschluss einen Wert zurรผckgeben.
- Ende der main()-Funktion.
C++ Virtuelle Funktion
Eine virtuelle Funktion ist eine weitere Mรถglichkeit, Laufzeitpolymorphismus zu implementieren in C++. Es handelt sich um eine spezielle Funktion, die in einer Basisklasse definiert und in der abgeleiteten Klasse neu definiert wird. Um eine virtuelle Funktion zu deklarieren, sollten Sie das Schlรผsselwort virtual verwenden. Das Schlรผsselwort sollte der Deklaration der Funktion in der Basisklasse vorangehen.
Wenn eine virtuelle Funktionsklasse geerbt wird, definiert die virtuelle Klasse die virtuelle Funktion entsprechend ihren Anforderungen neu. Zum Beispiel:
#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();
}
Ausgang:
Hier ist ein Screenshot des Codes:
Code Erlรคuterung:
- Fรผgen Sie die iostream-Headerdatei in den Code ein, um ihre Funktionen zu nutzen.
- Fรผgen Sie den std-Namespace in unseren Code ein, um seine Klassen zu verwenden, ohne ihn aufzurufen.
- Erstellen Sie eine Klasse mit dem Namen ClassA.
- Verwenden Sie den Modifikator fรผr den รถffentlichen Zugriff, um ein Klassenmitglied als รถffentlich zugรคnglich zu markieren.
- Erstellen Sie eine virtuelle Funktion namens show(). Es wird eine รถffentliche Veranstaltung sein.
- Der Text, der gedruckt werden soll, wenn show() aufgerufen wird. Das endl ist ein C++ Schlรผsselwort, das Zeilenende bedeutet. Es bewegt den Mauszeiger zur nรคchsten Zeile.
- Ende des Kรถrpers der virtuellen Funktion show().
- Ende des Rumpfes der Klasse ClassA.
- Erstellen einer neuen Klasse mit dem Namen ClassB, die die Klasse ClassA erbt. KlasseA wird zur Basisklasse, wรคhrend KlasseB zur abgeleiteten Klasse wird.
- Verwenden Sie den Modifikator fรผr den รถffentlichen Zugriff, um ein Klassenmitglied als รถffentlich zugรคnglich zu markieren.
- Definieren Sie die in der Basisklasse abgeleitete virtuelle Funktion show() neu.
- Der Text, der auf der Konsole gedruckt werden soll, wenn die in der abgeleiteten Klasse definierte Funktion show() aufgerufen wird.
- Ende des Hauptteils der show()-Funktion.
- Ende des Hauptteils der abgeleiteten Klasse, ClassB.
- Rufen Sie die Funktion main() auf. Die Programmlogik sollte in den Hauptteil eingefรผgt werden.
- Erstellen Sie eine Zeigervariable mit dem Namen a. Es zeigt auf die Klasse mit dem Namen ClassA.
- Erstellen Sie eine Instanz der Klasse mit dem Namen ClassB. Die Instanz erhรคlt den Namen b.
- Ordnen Sie die in der Adresse b gespeicherten Werte der Variablen a zu.
- Rufen Sie die in der abgeleiteten Klasse definierte Funktion show() auf. Die spรคte Bindung wurde implementiert.
- Ende des Hauptteils der main()-Funktion.
Polymorphismus zur Kompilierungszeit vs. Laufzeitpolymorphismus
Hier sind die Hauptunterschiede zwischen den beiden:
| Polymorphismus zur Kompilierungszeit | Laufzeitpolymorphismus |
|---|---|
| Es wird auch frรผhe Bindung oder statischer Polymorphismus genannt | Es wird auch spรคte/dynamische Bindung oder dynamischer Polymorphismus genannt |
| Die Methode wird wรคhrend der Kompilierungszeit aufgerufen/aufgerufen | Die Methode wird zur Laufzeit aufgerufen/aufgerufen |
| Implementiert durch Funktionsรผberladung und Operatorรผberladung | Implementiert รผber Methodenรผberschreibung und virtuelle Funktionen |
| Beispiel: Methodenรผberladung. Viele Methoden haben mรถglicherweise รคhnliche Namen, aber eine unterschiedliche Anzahl oder Art von Argumenten | Beispiel: Methodenรผberschreibung. Viele Methoden haben mรถglicherweise einen รคhnlichen Namen und denselben Prototyp. |
| Schnellere Ausfรผhrung, da die Methodenerkennung wรคhrend der Kompilierungszeit erfolgt | Langsamere Ausfรผhrung, da die Methodenerkennung zur Laufzeit erfolgt. |
| Less Da zur Kompilierungszeit alles bekannt ist, ist Flexibilitรคt bei der Problemlรถsung gegeben. | Da die Methoden wรคhrend der Laufzeit ermittelt werden, ist viel Flexibilitรคt beim Lรถsen komplexer Probleme gegeben. |
Zusammenfassung
- Polymorphismus bedeutet, viele Formen zu haben.
- Es tritt auf, wenn es eine Hierarchie von Klassen gibt, die durch Vererbung miteinander verbunden sind.
- Mit Polymorphismus kann sich eine Funktion je nach Objekt, das sie aufruft/aufruft, unterschiedlich verhalten.
- Beim Polymorphismus zur Kompilierungszeit wird die aufzurufende Funktion wรคhrend der Kompilierungszeit festgelegt.
- Beim Laufzeitpolymorphismus wird die aufzurufende Funktion wรคhrend der Laufzeit festgelegt.
- Polymorphismus zur Kompilierungszeit wird durch Funktionsรผberladung und Operatorรผberladung bestimmt.
- Bei der Funktionsรผberladung gibt es viele Funktionen mit รคhnlichen Namen, aber unterschiedlichen Argumenten.
- Die Parameter kรถnnen sich in Anzahl oder Typ unterscheiden.
- Bei der Operatorรผberladung wird eine neue Bedeutung definiert fรผr C++ durch.
- Laufzeitpolymorphismus wird durch Funktionsรผberschreibung erreicht.
- Beim รberschreiben von Funktionen gibt eine abgeleitete Klasse einer in der Basisklasse definierten Funktion eine neue Definition.







