-
Notifications
You must be signed in to change notification settings - Fork 0
05 Operatoren
Methodenüberladung ermöglicht es, mehrere Funktionen mit demselben Namen, aber unterschiedlichen Signaturen zu definieren. Die Signatur einer Methode setzt sich aus dem Namen, der Parameterliste und dem Namensraum bzw. der Klasse zusammen. Der Rückgabetyp ist dabei nicht Teil der Signatur.
Beispiel:
class Point {
double m_x, m_y, m_z;
public:
Point& move(double x, double y = 0, double z = 0);
Point& move(double delta[3]);
Point& move(const Point& p);
};In C++ können auch Operatoren überladen werden, um eine natürlichere Syntax zu ermöglichen, beispielsweise für mathematische Operationen. Es können jedoch keine neuen Operatoren erfunden werden, und die Vorrangregeln müssen eingehalten werden.
Beispiel:
Complex c1(2, 4), c2(2, -4);
Complex c = c1 + c2 / 10;Die meisten Operatoren können überladen werden, wie zum Beispiel +, -, *,
/, [], ==, !=, ->, und mehr. Einige Operatoren wie .
(Mitgliedsoperator) oder ?: (Ternärer Operator) können jedoch nicht überladen
werden.
Ab C++20 wurde der Spaceship Operator (<=>) eingeführt, der die
Vergleichsoperationen vereinfacht und ähnlich wie der compareTo-Operator in
Java funktioniert.
Operatoren können sowohl als Instanzmethoden als auch als freie Funktionen
implementiert werden. Freie Funktionen haben keinen versteckten this-Zeiger
und benötigen in der Regel friend-Deklarationen, um auf private Attribute
zugreifen zu können.
Beispiel einer Freundfunktion:
class Point {
public:
friend bool operator<(const Point& lhs, const Point& rhs);
};
bool operator<(const Point& lhs, const Point& rhs) {
return lhs.m_x < rhs.m_x;
}Der Indexoperator kann überladen werden, um auf bestimmte Elemente eines Objekts zuzugreifen. Die Rückgabe kann per Wert oder per Referenz erfolgen:
-
T operator[](int index) const(Rückgabe per Wert) -
T& operator[](int index)(Rückgabe per Referenz)
Der Zuweisungsoperator kann ebenfalls überladen werden, um eine tiefe Kopie zu ermöglichen. Der standardmäßig generierte Zuweisungsoperator erstellt eine flache Kopie (bitweise Kopie). Für Klassen, die dynamischen Speicher verwenden, ist es sinnvoll, einen eigenen Zuweisungsoperator zu definieren, um eine tiefe Kopie zu erstellen.
Der Inkrement- (++) und Dekrement- (--) Operator kann als Präfix- oder
Postfix-Version überladen werden:
-
Präfix (
T& operator++()) gibt den aktualisierten Wert zurück. -
Postfix (
T operator++(int)) gibt den alten Wert zurück.
Mit dem Typkonvertierungsoperator (operator T()) können benutzerdefinierte
Typkonvertierungen implementiert werden. Falls eine Konvertierung nur explizit
erlaubt sein soll, kann das Schlüsselwort explicit verwendet werden.
Beispiel:
explicit operator int() const {
return static_cast<int>(m_value);
}Benutzerdefinierte Literal-Operatoren ermöglichen es, eigene Literale zu
definieren, die an eine spezielle Bedeutung gebunden sind. Diese Literale werden
mit einem _suffix versehen.
Beispiel:
constexpr long double operator"" _km(long double d) { return d * 1000; }
constexpr long double operator"" _deg(long double d) { return d * 3.14159 / 180; }Verwendung:
auto dist = 10.0_km; // 10 Kilometer in MeterUm unnötige temporäre Objekte zu vermeiden, können Operatoren auch Move-Semantik unterstützen. Das ermöglicht, den Besitz eines temporären Objekts effizient zu übernehmen, anstatt eine Kopie zu erstellen.
Beispiel:
Matrix operator+(Matrix&& a, const Matrix& b) {
a += b;
return std::move(a);
}Diese Zusammenfassung bietet einen Überblick über das Überladen von Operatoren in C++ sowie einige praktische Anwendungsfälle wie den Zuweisungsoperator, den Spaceship Operator und Literal-Operatoren. Durch das Überladen von Operatoren kann der Code lesbarer und intuitiver gestaltet werden.