polymorphism c
Rolle des Polymorphismus in C ++ mit Beispielen.
Polymorphismus ist eine der vier Säulen der objektorientierten Programmierung. Polymorphismus bedeutet, viele Formen zu haben. Es kann als die Technik definiert werden, mit der ein Objekt je nach Situation viele Formen annehmen kann.
"Das Standard-Gateway ist nicht verfügbar."
In Bezug auf die Programmierung können wir sagen, dass sich ein Objekt unter verschiedenen Bedingungen unterschiedlich verhalten kann.
In diesem Tutorial lernen wir die Arten des Polymorphismus, die Möglichkeiten zur Implementierung des Polymorphismus sowie die verschiedenen anderen Konzepte des Polymorphismus im Detail kennen.
=> Hier finden Sie A-Z der C ++ - Schulungsanleitungen.
Zum Beispiel, Eine Frau kann in verschiedenen Situationen viele Rollen übernehmen. Für ein Kind ist sie eine Mutter, eine Hausfrau zu Hause, eine Arbeiterin im Büro usw. Eine Frau übernimmt also unterschiedliche Rollen und zeigt unter verschiedenen Bedingungen ein unterschiedliches Verhalten. Dies ist ein reales Beispiel für Polymorphismus.
Ähnlich können wir auch in der Programmierwelt einen Operator '+' haben, der der binäre Additionsoperator ist, der sich anders ändert, wenn sich die Operanden ändern. Zum Beispiel, Wenn beide Operanden numerisch sind, wird eine Addition durchgeführt.
Wenn die Operanden dagegen Zeichenfolgen sind, fungiert sie als Verkettungsoperator. Polymorphismus bedeutet also auf den Punkt gebracht, dass eine Entität viele Formen annimmt oder sich unter verschiedenen Bedingungen unterschiedlich verhält.
Was du lernen wirst:
- Arten von Polymorphismus
- Compile Time Polymorphism Vs. Laufzeitpolymorphismus
- Kompilierungszeitpolymorphismus
- Funktionsüberladung
- Überlastung des Bedieners
- Fazit
- Literatur-Empfehlungen
Arten von Polymorphismus
Polymorphismus wird in zwei Typen unterteilt.
- Kompilierungszeitpolymorphismus
- Laufzeitpolymorphismus
Das Diagramm, um dies darzustellen, ist unten gezeigt:
Wie im obigen Diagramm gezeigt, wird der Polymorphismus in Polymorphismus zur Kompilierungszeit und Laufzeitpolymorphismus unterteilt. Der Polymorphismus der Kompilierungszeit ist weiter unterteilt in Operatorüberladung und Funktionsüberladung. Der Laufzeitpolymorphismus wird mithilfe virtueller Funktionen weiter implementiert.
Der Polymorphismus zur Kompilierungszeit wird auch als frühe Bindung oder statischer Polymorphismus bezeichnet. Bei dieser Art von Polymorphismus wird die Methode des Objekts zur Kompilierungszeit aufgerufen. Bei Laufzeitpolymorphismus wird die Methode des Objekts zur Laufzeit aufgerufen.
Laufzeitpolymorphismus ist auch als dynamische oder späte Bindung oder dynamischer Polymorphismus bekannt. In den folgenden Themen werden wir uns mit der detaillierten Implementierung jeder dieser Techniken befassen.
Compile Time Polymorphism Vs. Laufzeitpolymorphismus
Lassen Sie uns die Hauptunterschiede zwischen Kompilierungszeit und Laufzeitpolymorphismus unten sehen.
Kompilierungszeitpolymorphismus | Laufzeitpolymorphismus |
---|---|
Auch als statischer Polymorphismus oder frühe Bindung bekannt | Auch als dynamischer Polymorphismus oder späte / dynamische Bindung bekannt |
Die Objects-Methode wird zur Kompilierungszeit aufgerufen | Die Objektmethode wird zur Laufzeit aufgerufen |
Wird normalerweise durch Überladen von Bedienern und Überladen von Funktionen implementiert | Implementiert mit virtuellen Funktionen und Methodenüberschreibung |
Das Überladen von Methoden ist ein Polymorphismus zur Kompilierungszeit, bei dem mehr als eine Methode denselben Namen, aber unterschiedliche Parameterlisten und -typen haben kann. | Das Überschreiben von Methoden ist ein Laufzeitpolymorphismus, bei dem mehr als eine Methode denselben Namen mit demselben Prototyp hat |
Da Methoden zur Kompilierungszeit bekannt sind, ist die Ausführung schneller | Die Ausführung ist langsamer, da die Methode zur Laufzeit bekannt ist |
Bieten Sie weniger Flexibilität bei der Implementierung von Lösungen, da bei der Kompilierung alles bekannt sein muss | Weitaus flexibler für die Implementierung komplexer Lösungen, da die Methoden zur Laufzeit festgelegt werden |
Kompilierungszeitpolymorphismus
Der Polymorphismus der Kompilierungszeit ist eine Technik, bei der die Methode eines Objekts zur Kompilierungszeit aufgerufen wird.
Diese Art von Polymorphismus wird auf zwei Arten implementiert.
- Funktionsüberladung
- Überlastung des Bedieners
Wir werden jede Technik im Detail diskutieren.
Funktionsüberladung
Eine Funktion wird als überladen bezeichnet, wenn wir mehr als eine Funktion mit demselben Namen, aber unterschiedlichen Parametertypen oder einer unterschiedlichen Anzahl von Argumenten haben.
Somit kann eine Funktion basierend auf den Parametertypen, der Reihenfolge der Parameter und der Anzahl der Parameter überladen werden.
Beachten Sie, dass zwei Funktionen mit demselben Namen und derselben Parameterliste, aber unterschiedlichem Rückgabetyp keine überladene Funktion sind und bei Verwendung im Programm zu einem Kompilierungsfehler führen.
Wenn sich Funktionsparameter nur im Zeiger unterscheiden und der Array-Typ äquivalent ist, sollte er nicht zum Überladen verwendet werden.
Andere Typen wie statisch und nicht statisch, const und flüchtig usw. Oder Parameterdeklarationen, die sich in Vorhandensein oder Nichtvorhandensein von Standardwerten unterscheiden, dürfen ebenfalls nicht zum Überladen verwendet werden, da sie aus Sicht der Implementierung gleichwertig sind.
Zum Beispiel,Die folgenden Funktionsprototypen sind überladene Funktionen.
Add(int,int); Add(int,float); Add(float,int); Add(int,int,int);
In den obigen Prototypen sehen wir, dass wir die Funktion Hinzufügen basierend auf der Art der Parameter, der Reihenfolge oder Reihenfolge der Parameter, der Anzahl der Parameter usw. überladen.
Nehmen wir ein vollständiges Programmierbeispiel, um das Überladen von Funktionen besser zu verstehen.
#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< Ausgabe:
35
191
19
Hallo Welt
Im obigen Programm haben wir eine Summationsklasse, die drei überladene Funktionen mit dem Namen Add definiert, die zwei Ganzzahlargumente, drei Ganzzahlargumente und zwei Zeichenfolgenargumente akzeptiert.
In der Hauptfunktion führen wir vier Funktionsaufrufe durch, die verschiedene Parameter bereitstellen. Die ersten beiden Funktionsaufrufe sind unkompliziert. Im dritten Funktionsaufruf zum Hinzufügen geben wir zwei Gleitkommawerte als Argumente an.
In diesem Fall lautet die übereinstimmende Funktion int Add (int, int), da intern der float in double konvertiert und dann mit der Funktion mit den int-Parametern abgeglichen wird. Wenn wir double anstelle von float angegeben hätten, hätten wir eine weitere überladene Funktion mit double als Parametern.
Der letzte Funktionsaufruf verwendet Zeichenfolgenwerte als Parameter. In diesem Fall fungiert der Operator Hinzufügen (+) als Verkettungsoperator und verkettet die beiden Zeichenfolgenwerte, um eine einzelne Zeichenfolge zu erzeugen.
Vorteile der Funktionsüberlastung
Der Hauptvorteil der Funktionsüberladung besteht darin, dass die Wiederverwendbarkeit von Code gefördert wird. Wir können so viele Funktionen wie möglich mit demselben Namen haben, solange sie basierend auf dem Argumenttyp, der Argumentsequenz und der Anzahl der Argumente überladen sind.
Auf diese Weise wird es einfacher, verschiedene Funktionen mit demselben Namen zu haben, um das Verhalten derselben Operation unter verschiedenen Bedingungen darzustellen.
Wenn keine Funktionsüberladung vorhanden wäre, hätten wir zu viele verschiedene Arten von Funktionen mit unterschiedlichen Namen schreiben müssen, wodurch der Code unlesbar und schwer anzupassen wäre.
Überlastung des Bedieners
Operatorüberladung ist die Technik, mit der wir den vorhandenen Operatoren in C ++ eine andere Bedeutung geben. Mit anderen Worten, wir überladen die Operatoren, um den benutzerdefinierten Datentypen als Objekte eine besondere Bedeutung zu geben.
Die meisten Operatoren in C ++ sind überladen oder haben eine besondere Bedeutung, damit sie mit benutzerdefinierten Datentypen arbeiten können. Beachten Sie, dass beim Überladen die Grundbedienung der Bediener nicht geändert wird. Überladen gibt dem Operator lediglich eine zusätzliche Bedeutung, indem seine grundlegende Semantik gleich bleibt.
Obwohl die meisten Operatoren in C ++ überladen werden können, gibt es einige Operatoren, die nicht überladen werden können.
Diese Operatoren sind in der folgenden Tabelle aufgeführt.
Betreiber Scope Resolution Operator (: :) Größe von Mitgliedsauswahl (.) Elementzeigerauswahl (*) ternärer Operator (? :)
Die Funktionen, mit denen wir Operatoren überladen, heißen „ Bedienerfunktionen ”.
Die Bedienerfunktionen ähneln den normalen Funktionen, unterscheiden sich jedoch. Der Unterschied besteht darin, dass der Name der Operatorfunktionen mit dem Schlüsselwort „ Operator ”Gefolgt vom Bedienersymbol, das überladen werden soll.
Die Operatorfunktion wird dann aufgerufen, wenn der entsprechende Operator im Programm verwendet wird. Diese Operatorfunktionen können Mitgliedsfunktionen oder globale Methoden oder sogar eine Freundfunktion sein.
Die allgemeine Syntax der Operatorfunktion lautet:
return_type classname::operator op(parameter list) { //function body }
Hier ist 'operator op' die Operatorfunktion, bei der der Operator das Schlüsselwort und op der zu überladende Operator ist. Return_type ist der zurückzugebende Werttyp.
Lassen Sie uns einige Programmierbeispiele sehen, um die Überladung des Bedieners mithilfe von Bedienerfunktionen zu demonstrieren.
undefinierter Verweis auf Haupt-C ++
Beispiel 1:Überladung des unären Operators mit der Member-Operator-Funktion.
#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; }
Ausgabe:
Inkrementierter Fußwert: 10
Hier haben wir den unären Inkrementoperator mit der Funktion operator ++ überladen. In der Hauptfunktion verwenden wir diesen ++ - Operator, um das Objekt der Klasse Distance zu erhöhen.
Beispiel 2:Überladung des Binäroperators mit der Member-Operator-Funktion.
#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(); }
Ausgabe:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Hier haben wir das klassische Beispiel der Addition von zwei komplexen Zahlen unter Verwendung der Operatorüberladung verwendet. Wir definieren eine Klasse zur Darstellung komplexer Zahlen und eine Operatorfunktion zur Überladung + Operator, in der wir den Real- und Imaginärteil komplexer Zahlen hinzufügen.
In der Hauptfunktion deklarieren wir zwei komplexe Objekte und fügen sie mit dem Operator overloaded + hinzu, um das gewünschte Ergebnis zu erhalten.
Im folgenden Beispiel werden wir die Friend-Funktion verwenden, um zwei komplexe Zahlen hinzuzufügen, um den Unterschied in der Implementierung zu sehen.
#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(); }
Ausgabe:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Wir sehen, dass die Ausgabe des Programms dieselbe ist. Der einzige Unterschied in der Implementierung besteht in der Verwendung der Friend-Funktion zum Überladen des Operators + anstelle einer Member-Funktion in der vorherigen Implementierung.
Wenn die Friend-Funktion für einen binären Operator verwendet wird, müssen wir beide Operanden für die Funktion explizit angeben. In ähnlicher Weise müssen wir den einzelnen Operanden für die Funktion bereitstellen, wenn der unäre Operator mit der Friend-Funktion überladen ist.
Neben den Operatorfunktionen können wir auch a schreiben Konvertierungsoperator Dies wird verwendet, um von einem Typ in einen anderen zu konvertieren. Diese überladenen Konvertierungsoperatoren sollten eine Mitgliedsfunktion der Klasse sein.
Beispiel 3:Überladung des Operators mit dem Konvertierungsoperator.
#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)= '< Ausgabe:
Der resultierende Wert der gegebenen Fraktion (3,5) = 0,6
In diesem Programm haben wir den Konvertierungsoperator verwendet, um den angegebenen Bruch in einen Gleitkommawert zu konvertieren. Sobald die Konvertierung abgeschlossen ist, gibt der Konvertierungsoperator den resultierenden Wert an den Aufrufer zurück.
Wenn wir in der Hauptfunktion das df-Objekt einer res_val-Variablen zuweisen, erfolgt die Konvertierung und das Ergebnis wird in res_val gespeichert.
Wir können auch einen Konstruktor mit einem einzigen Argument aufrufen. Wenn wir einen Konstruktor aus der Klasse mit einem einzigen Argument aufrufen können, wird dies als „ Umwandlung Baumeister ”. Der Konvertierungskonstruktor kann für die implizite Konvertierung in die zu erstellende Klasse verwendet werden.
#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 = '< Ausgabe:
Punkt konstruiert mit normalem Konstruktor
x = 20 y = 30
Mit dem Konvertierungskonstruktor konstruierter Punkt
x = 10 y = 0

Hier haben wir einen Klassenpunkt, der einen Konstruktor mit Standardwerten definiert. In der Hauptfunktion konstruieren wir ein Objekt pt mit x- und y-Koordinaten. Als nächstes weisen wir pt einfach einen Wert von 10 zu. Hier wird der Konvertierungskonstruktor aufgerufen und x wird ein Wert von 10 zugewiesen, während y den Standardwert 0 erhält.
Regeln zum Überladen von Bedienern
Bei der Überladung von Bedienern müssen die folgenden Regeln beachtet werden.
- In C ++ können wir nur die vorhandenen Operatoren überladen. Neu hinzugefügte Operatoren können nicht überladen werden.
- Wenn Operatoren überladen sind, müssen wir sicherstellen, dass mindestens einer der Operanden vom benutzerdefinierten Typ ist.
- Um bestimmte Operatoren zu überlasten, können wir auch die Friend-Funktion verwenden.
- Wenn wir unäre Operatoren mit einer Member-Funktion überladen, werden keine expliziten Argumente verwendet. Es ist ein explizites Argument erforderlich, wenn der unäre Operator mithilfe der Friend-Funktion überladen wird.
- In ähnlicher Weise müssen wir, wenn Binäroperatoren mit der Elementfunktion überladen werden, ein explizites Argument für die Funktion angeben. Wenn binäre Operatoren mit der Friend-Funktion überladen werden, akzeptiert die Funktion zwei Argumente.
- In C ++ gibt es zwei Operatoren, die bereits überladen sind. Dies sind '=' und '&'. Um ein Objekt derselben Klasse zu kopieren, müssen wir den Operator = nicht überladen und können ihn direkt verwenden.
Vorteile der Überlastung des Bedieners
Durch das Überladen von Operatoren in C ++ können wir die Funktionalität von Operatoren auf die benutzerdefinierten Typen erweitern, einschließlich der Klassenobjekte zusätzlich zu den integrierten Typen.
Durch die Erweiterung der Operatorfunktionalität auf benutzerdefinierte Typen müssen wir keinen komplexen Code schreiben, um verschiedene Operationen für benutzerdefinierte Typen auszuführen. Wir können dies jedoch in einer Operation selbst ausführen, genau wie bei den integrierten Typen.
Fazit
Der Polymorphismus zur Kompilierungszeit bietet eine Überladungsfunktion, die hauptsächlich dazu dient, die Funktionalität des Codes in Bezug auf Funktionsüberladung und Operatorüberladung zu erweitern.
Durch Überladen von Funktionen können wir mehr als eine Funktion mit demselben Namen, aber unterschiedlichen Parametern und Typen schreiben. Dies macht den Code einfach und leicht lesbar. Durch das Überladen von Operatoren können wir die Funktionalität von Operatoren erweitern, sodass wir auch grundlegende Operationen für benutzerdefinierte Typen ausführen können.
In unserem nächsten Tutorial erfahren Sie mehr über den Laufzeitpolymorphismus in C ++.
=> Lesen Sie die Easy C ++ - Schulungsserie durch.
Literatur-Empfehlungen
- Laufzeitpolymorphismus In C ++
- Friend-Funktionen in C ++
- Rekursion in C ++
- Python-Hauptfunktions-Tutorial mit praktischen Beispielen
- Ein vollständiger Überblick über C ++
- QTP-Tutorial Nr. 21 - So machen Sie QTP-Tests mithilfe von Aktionen und Funktionsbibliotheken modular und wiederverwendbar
- Unix Pipes Tutorial: Pipes in der Unix-Programmierung
- Bibliotheksfunktionen in C ++