Der Indexzugriffsoperator operator[] ist ein überladbarer Operator in C++, der die Syntax für das Indizieren von Objekten benutzerdefinierter Container (z.B. wie bei Arrays) bereitstellt.
Hintergrund:
In der Sprache C und später auch in C++ ermöglichte der Operator [] einen schnellen und einfachen Zugriff auf die Elemente eines Arrays über den Index. Mit dem Anstieg der Popularität von Containerklassen entstand die Notwendigkeit, dieselbe Syntax auf benutzerdefinierte Datentypen zu übertragen.
Problem:
Das korrekte Design von Indexzugriffsoperatoren ist mit Fragen der Konstantheit, der Sicherheit gegen Überlauf (out-of-bounds), der Wahl des Rückgabewerts und der Garantie der Gültigkeit von Referenzen oder Zeigern verbunden.
Lösung:
In C++ kann man operator[] für Klassen überladen, um den Zugriff auf Elemente über den Index zu ermöglichen und "Array-ähnliches Verhalten" zu implementieren. Beide Versionen des Operators müssen implementiert werden: eine normale (für nicht-konstante Objekte) und eine konstante (für konstante Objekte).
Beispielcode:
class MyArray { int data[10]; public: int& operator[](size_t index) { return data[index]; } const int& operator[](size_t index) const { return data[index]; } }; MyArray arr; arr[3] = 42; // OK const MyArray& const_arr = arr; int val = const_arr[3]; // OK
Wichtige Merkmale:
.at() in Standardcontainern)Ist die Rückgabe einer Referenz aus operator[] erforderlich?
Nein — aber wenn man einen Wert zurückgibt, wird die Syntax arr[i] = x; nicht funktionieren (man würde kopieren, anstatt zuzuweisen). Um die gewohnte Semantik des Containers zu unterstützen, gibt man normalerweise eine Referenz zurück. Wenn man einen Wert zurückgibt, wird das Schreiben in das Element nicht funktionieren:
int operator[](size_t idx); // arr[2] = 10; wird nicht kompilieren
Sollte operator[] eine Begrenzungsprüfung durchführen?
Der Standard verlangt dies nicht. Der klassische operator[] (wie in std::vector) führt solche Prüfungen NICHT durch. Für Prüfungen führen die Standardcontainer eine separate Methode .at() ein, die eine Ausnahme auslöst, wenn man den Indexbereich überschreitet.
Kann operator[] eine konstante Methode sein?
Nein — wenn Sie eine nicht-konstante Referenz zurückgeben. Man muss operator[] jedoch sowohl für konstante als auch für nicht-konstante Objekte überladen, damit der Container intuitiv und sicher funktioniert.
Ein junger Entwickler implementierte nur die nicht-konstante Version von operator[], die nach Wert zurückgibt. Infolgedessen konnte der Container nicht über eine const-Referenz aufgerufen werden, und alle Schreibversuche funktionierten seltsam — die Werte wurden nicht gespeichert.
Vorteile:
Nachteile:
In dem Container MyArray wurden beide Versionen von operator[] mit korrekter Rückgabe von Referenzen implementiert. Bei Bedarf wurde die Methode at() mit einer Begrenzungsprüfung hinzugefügt.
Vorteile:
Nachteile: