Skip to content

05 Operatoren

gideon edited this page Oct 24, 2024 · 1 revision

Zusammenfassung der Slides "Operatoren in C++"

Überladen von Methoden

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);
};

Überladen von Operatoren

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;

Überladbare Operatoren

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 als Instanzmethoden vs. freie Funktionen

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;
}

Index-Operator []

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)

Zuweisungsoperator =

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.

Inkrement- und Dekrement-Operatoren

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.

Typkonvertierungsoperator

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);
}

Literal-Operatoren

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 Meter

Operatoren mit Move-Semantik

Um 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.