Einführung in die Operatorüberladung
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 40 von 104.
Operatorüberladung ermöglicht es Ihnen zu definieren, wie sich Operatoren wie +, -, oder == verhalten, wenn sie mit Ihren benutzerdefinierten Klassen verwendet werden. Anstatt Methoden wie a.add(b) aufzurufen, können Sie das intuitivere a + b schreiben.
In C++ sind Operatoren im Wesentlichen Funktionen mit speziellen Namen. Um einen Operator zu überladen, definieren Sie eine Funktion unter Verwendung des Schlüsselworts operator, gefolgt von dem Symbol:
class Vector2D {
double x, y;
public:
Vector2D(double x, double y) : x(x), y(y) {}
// Den +-Operator überladen
Vector2D operator+(const Vector2D& other) const {
return Vector2D(x + other.x, y + other.y);
}
};Jetzt können Sie zwei Vektoren auf natürliche Weise addieren:
Vector2D v1(1.0, 2.0);
Vector2D v2(3.0, 4.0);
Vector2D v3 = v1 + v2; // Ruft v1.operator+(v2) aufNicht alle Operatoren können überladen werden. Der Bereichsauflösungsoperator ::, der Elementzugriff ., der Ternär-Operator ?: und sizeof können nicht überladen werden. Zusätzlich können Sie keine neuen Operatoren erstellen oder die Rangfolge eines Operators ändern – * wird immer vor + ausgewertet.
Operatoren können als Memberfunktionen (wie oben) oder als Nicht-Memberfunktionen implementiert werden. In den kommenden Lektionen werden Sie lernen, wann welcher Ansatz zu verwenden ist und wie man spezifische Kategorien von Operatoren überlädt.
Aufgabe
EinfachLassen Sie uns eine Point-Klasse erstellen, die eine 2D-Koordinate darstellt und das Addieren von zwei Punkten mit dem +-Operator unterstützt. Dies ist Ihr erster Schritt in die Operatorüberladung – damit Ihre benutzerdefinierten Klassen mit vertrauten Operatoren funktionieren.
Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:
Point.h: Definieren Sie einePoint-Klasse, die x- und y-Koordinaten speichert (beideint). Ihre Klasse sollte Folgendes enthalten:- Private Member für die x- und y-Koordinaten
- Einen Konstruktor, der x- und y-Werte entgegennimmt
- Getter
getX()undgetY()(beide const) - Einen überladenen
+-Operator, der zwei Punkte addiert und einen neuenPointmit den kombinierten Koordinaten zurückgibt
Der
+-Operator sollte als Elementfunktion implementiert werden, die einen weiterenPointals const-Referenz entgegennimmt und einen neuenPointzurückgibt. Markieren Sie ihn alsconst, da er keinen der Operanden verändert.main.cpp: Lesen Sie vier Ganzzahlen von der Eingabe ein (x1, y1, x2, y2 in separaten Zeilen), die zwei Punkte darstellen. Erstellen Sie zweiPoint-Objekte, addieren Sie diese mit dem+-Operator und zeigen Sie die Ergebnisse an.Ausgabeformat:
Point 1: (<x1>, <y1>) Point 2: (<x2>, <y2>) Sum: (<sum_x>, <sum_y>)
Die entscheidende Erkenntnis hierbei ist, dass p1 + p2 hinter den Kulissen eigentlich p1.operator+(p2) aufruft. Ihr überladener Operator ermöglicht es Ihnen, intuitiven Code wie Point p3 = p1 + p2; anstelle von etwas wie Point p3 = p1.add(p2); zu schreiben.
Konvertieren Sie Eingabestrings mit std::stoi() in Ganzzahlen. Vergessen Sie nicht die Header-Guards in Ihrer Header-Datei.
Spickzettel
Operatorüberladung ermöglicht es Ihnen zu definieren, wie sich Operatoren wie +, - oder == bei benutzerdefinierten Klassen verhalten, was eine intuitive Syntax wie a + b anstelle von a.add(b) ermöglicht.
Um einen Operator zu überladen, definieren Sie eine Funktion mit dem Schlüsselwort operator, gefolgt von dem Symbol:
class Vector2D {
double x, y;
public:
Vector2D(double x, double y) : x(x), y(y) {}
// Den +-Operator überladen
Vector2D operator+(const Vector2D& other) const {
return Vector2D(x + other.x, y + other.y);
}
};Verwendung:
Vector2D v1(1.0, 2.0);
Vector2D v2(3.0, 4.0);
Vector2D v3 = v1 + v2; // Ruft v1.operator+(v2) aufEinige Operatoren können nicht überladen werden: ::, ., ?: und sizeof. Sie können keine neuen Operatoren erstellen oder die Operatorrangfolge ändern.
Operatoren können als Member-Funktionen oder Nicht-Member-Funktionen implementiert werden.
Probier es selbst
#include <iostream>
#include <string>
#include "Point.h"
using namespace std;
int main() {
// Eingabe lesen
string line1, line2, line3, line4;
getline(cin, line1);
getline(cin, line2);
getline(cin, line3);
getline(cin, line4);
int x1 = stoi(line1);
int y1 = stoi(line2);
int x2 = stoi(line3);
int y2 = stoi(line4);
// TODO: Erstelle zwei Point-Objekte unter Verwendung der Eingabewerte
// TODO: Addiere die beiden Punkte mit dem + Operator
// TODO: Gib die Ergebnisse im erforderlichen Format aus:
// Point 1: (<x1>, <y1>)
// Point 2: (<x2>, <y2>)
// Sum: (<sum_x>, <sum_y>)
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamensräume & GültigkeitsbereicheEinführung in OOP in C++Klassen vs. ObjekteDer 'this'-PointerMethoden (Elementfunktionen)Attribute (Datenelemente)Grundlagen zu Ctors & DtorsRückblick - Einfacher Taschenrechner4Klasseneigenschaften
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen & KlassenZusammenfassung - Bankkonto-Manager7Vererbung
Grundlagen der VererbungZugriffsstufen bei VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick - Mitarbeiter-Hierarchie2Speicherverwaltung
Stack vs. Heap SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Smart Pointers in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsspezifizierer in C++Zugriffsspezifizierer im DetailInformation HidingStruct vs. ClassVerschachtelte & innere KlassenRückblick - Studentenverwaltungssystem8Polymorphie
Kompilierzeit- vs. Laufzeit-PolymorphieFunktionsüberladungVirtuelle Funktionen – WiederholungRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIZusammenfassung – Formen-Rechner3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorVerschiebekonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktoren im DetailRule of Three / Five / ZeroZusammenfassung - String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladen der [] und () OperatorenTypumwandlungsoperatorenRückblick - Matrix-Klasse9Templates
FunktionstemplatesKlassentemplatesTemplate-SpezialisierungVariadische TemplatesSFINAE & Type Traits GrundlagenRückblick - Generische Container