Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Operatorüberladung | Überblick Über Polymorphismus
C++ OOP
course content

Kursinhalt

C++ OOP

C++ OOP

1. Grundlagen der OOP in C++
2. Konstruktoren und Destruktoren
3. Kapselungsübersicht
4. Überblick Über die Vererbung
5. Überblick Über Polymorphismus

book
Operatorüberladung

Operatorüberladung ist ein leistungsstarkes Merkmal in objektorientierten Programmiersprachen, das es Ihnen ermöglicht, das Verhalten von Operatoren für benutzerdefinierte Klassen neu zu definieren. Durch das Überladen von Operatoren können Sie benutzerdefinierte Implementierungen für Operationen bereitstellen, die Objekte Ihrer Klasse betreffen, was zu intuitiverem und ausdrucksstärkerem Code führt.

Die Syntax der Operatorüberladung

Das Überladen wird erreicht, indem spezielle Memberfunktionen oder Freundfunktionen definiert werden, die das gewünschte Verhalten für den Operator implementieren. Die Syntax für das Überladen von Operatoren variiert je nach Operator, den Sie überladen möchten. Die allgemeine sieht so aus:

Die Syntax, oder genauer gesagt, die Anzahl der Parameter und der Rückgabetyp, hängt auch davon ab, ob Sie Operatoren als Memberfunktionen oder Freundfunktionen überladen. Betrachten Sie die folgenden zwei Beispiele:

h

Member

h

Friend

copy
123456
class Example { public: Example operator+ (const Example& other) { // Define behavior for operator+ } };

Die Tabelle der Operatoren, die überladen werden können

Hier ist eine Tabelle, die alle Operatoren auflistet, die überladen werden können. Es ist jedoch wichtig zu beachten, dass es zwar möglich ist, diese Operatoren zu überladen, es jedoch absolut nicht notwendig ist, alle für Ihre Klassen zu überladen.

()
Funktionsaufruf
function()
[]
Array-Indizierung
array[index]
++ --
Inkrement/Dekrement
++a, a--, etc.
+ - * / %
Arithmetische Operationen
a + b, a - b, etc.
+= -= *= /=
Zuweisungsoperationen
a += b, a -= b, etc.
== != < >
Vergleichsoperationen
a == b, a < b, etc.
<< >>
Stream-Einfügen/-Extraktion
cout << a, cin >> a

Wir werden uns auf die am häufigsten verwendeten Operatoren konzentrieren, einschließlich Stream-Einfügen und Extraktion, arithmetische Operatoren, Inkrement- und Dekrement-Operatoren.

Überladen von Stream-Einfügeoperatoren

Um die Operatoren << und >> für eine Klasse zu überladen, definieren Sie typischerweise eine Freundfunktion oder eine Memberfunktion, die einen Ausgabestream (std::ostream&) oder Eingabestream (std::istream&) als linken Operanden und ein Objekt Ihrer Klasse als rechten Operanden nimmt. Diese Funktion formatiert dann die Daten des Objekts und streamt sie zum Ausgabestream.

h

Point

copy
123456789101112131415
class Point { public: friend std::ostream& operator<<(std::ostream& out, const Point& point); friend std::istream& operator>>(std::istream& in, Point& point); private: int x, y; }; std::ostream& operator<<(std::ostream& out, const Point& point) { return out << "x: " << point.x << ", y: " << point.y << std::endl; } std::istream& operator>>(std::istream& in, Point& point) { return in >> point.x >> point.y; }

Das Überladen von Stream-Einfügeoperatoren, wie <<, ermöglicht es Ihnen, benutzerdefiniertes Ausgabeverhalten für Objekte Ihrer Klassen zu definieren, wenn sie zu einem Ausgabestream, wie std::cout, gestreamt werden. Diese Funktion ist besonders nützlich, um die Lesbarkeit und Benutzerfreundlichkeit Ihres Codes zu verbessern, wenn Sie mit benutzerdefinierten Datentypen arbeiten.

Hinweis

Das Überladen des << Operators für Ausgabestreams ist häufiger als das Überladen des >> Operators für Eingabestreams, da Eingabeoperationen mit >> fehleranfälliger sein können fehleranfälliger.

Überladen von arithmetischen Operatoren

Sie können andere arithmetische Operatoren (-, *, /, %) auf ähnliche Weise überladen, um benutzerdefinierte Operationen mit Ihren benutzerdefinierten Typen durchzuführen.

cpp

main

copy
12345678910111213141516171819202122
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} Point operator+(const Point& other) { return Point(x + other.x, y + other.y); } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p = Point(2, 4) + Point(2, 6); std::cout << p.getX() << ' ' << p.getY() << std::endl; }

In diesem Beispiel überladen wir als Mitgliedsfunktion der Point Klasse. Es nimmt ein anderes Point Objekt als Parameter und gibt ein neues Point Objekt zurück, das die Summe der beiden Punkte darstellt. Sie können + durch -, *, /, % ersetzen und die Implementierungslogik ein wenig anpassen.

Inkrement und Dekrement

Sie können sowohl die Präfix- als auch die Postfix-Inkrement- und Dekrementoperatoren (++ und --) für Ihre benutzerdefinierten Klassen überladen. Beginnen wir mit dem Präfix:

cpp

main

copy
123456789101112131415161718192021222324
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} // Prefix increment operator (++point) Point& operator++() { ++x; ++y; return *this; } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p(2, 2); ++p; std::cout << p.getX() << ' ' << p.getY() << std::endl; }

Hinweis

Der Dekrementoperator wird ähnlich wie der Inkrementoperator überladen, mit dem -- Operator und der Subtraktionsoperation.

Wie Sie sehen, ist es nicht schwer, den Präfix-Inkrement- und Dekrementoperator zu überladen. Es wird jedoch kniffliger, wenn es um den Postfix geht. Wie Sie sich erinnern, gibt es eine Reihenfolge der Ausführung von Postfix- und Präfix-Inkrement. Nehmen wir an, wir haben die Variable x mit dem Wert 5.

++Präfix
++x
ergibt 6
Inkrementieren, dann verwenden
Postfix++
x++
ergibt 5
Verwenden, dann inkrementieren
--Präfix
--x
ergibt 4
Dekrementieren, dann verwenden
Postfix--
x--
ergibt 5
Verwenden, dann dekrementieren

Beim Überladen von Postfix-Inkrement und -Dekrement müssen wir auch die Reihenfolge der Ausführung implementieren. Es wird ungefähr so aussehen:

cpp

main

copy
1234567891011121314151617181920212223242526
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} // Postfix increment operator (point++) Point operator++(int) { Point temp = *this; // Creating a temp variable ++(this->x); // Incrementing original Point's x ++(this->y); // Incrementing original Point's y return temp; // Returning created temp variable } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p(2, 2); p++; std::cout << p.getX() << ' ' << p.getY() << std::endl; }

Hinweis

Der ganzzahlige Parameter wird ohne Argumentnamen übergeben, um dem Compiler lediglich zu signalisieren, dass es sich um den Postfix-Inkrementoperator handelt, der überladen wird. Dies ist notwendig, da sich die Deklaration von Präfix- und Postfix-Operatoren in keiner anderen Weise unterscheidet.

In der Implementierung des Postfix-Inkrementoperators wird der ursprüngliche Wert des Objekts in einer temporären Variablen (temp) gespeichert. Während das aktuelle Objekt dann inkrementiert wird, ist der vom Operator zurückgegebene Wert derjenige, der in temp gespeichert ist. Somit wird die Variable inkrementiert, aber die Inkrementierung wirkt sich erst im nächsten Ausdruck aus, da der Operator den ursprünglichen Wert zurückgibt.

Was bedeutet Operatorüberladung?

Was bedeutet Operatorüberladung?

Wählen Sie die richtige Antwort aus

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 5. Kapitel 4
We're sorry to hear that something went wrong. What happened?
some-alt