L'opérateur d'accès par index operator[] est un opérateur surchargé en C++ permettant de fournir une syntaxe d'indexation sur des objets de conteneurs personnalisés (par exemple, similaire aux tableaux).
Historique de la question :
Dans le langage C, puis en C++, l'opérateur [] permettait d'accéder rapidement et facilement aux éléments d'un tableau par index. Cependant, avec l'essor des classes de conteneurs, il est devenu nécessaire de transférer cette même syntaxe aux types de données personnalisés.
Problème :
La conception correcte des opérateurs d'accès par index soulève des questions de constance, de sécurité contre les débordements (out-of-bounds), de choix de valeur de retour et de garantie de validité de la référence ou du pointeur.
Solution :
En C++, il est possible de surcharger operator[] pour des classes, permettant ainsi un accès aux éléments par index et d'implémenter un "comportement similaire à un tableau". Il faut implémenter les deux versions de l'opérateur - ordinaire (pour les objets non constants) et constante (pour les objets constants).
Exemple de code :
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
Caractéristiques clés :
.at() dans les conteneurs standard)Le retour d'une référence depuis operator[] est-il obligatoire ?
Non - mais si vous retournez une valeur, la syntaxe arr[i] = x; ne fonctionnera pas (vous allez copier au lieu d'assigner). Pour maintenir la sémantique habituelle du conteneur, on retourne généralement une référence. Si vous retournez une valeur, l'écriture d'un élément ne fonctionnera pas :
int operator[](size_t idx); // arr[2] = 10; ne compilera pas
operator[] doit-il vérifier les limites ?
La norme ne l'exige pas. L'opérateur classique operator[] (comme dans std::vector) NE fait pas de telles vérifications. Pour des vérifications, les conteneurs standards introduisent une méthode distincte .at(), qui lance une exception en cas de dépassement de bord.
operator[] peut-il être une méthode constante ?
Non - si vous retournez une référence non constante. Cependant, il est nécessaire de surcharger operator[] à la fois pour les objets constants et non constants, afin que le conteneur fonctionne de manière intuitive et sécurisée.
Un jeune développeur a uniquement implémenté la version non constante de operator[], retournant par valeur. En conséquence, le conteneur ne pouvait pas être accédé via une référence const, et toute tentative d'écriture agissait de manière étrange – les valeurs n'étaient pas conservées.
Avantages :
Inconvénients :
Dans le conteneur MyArray, les deux versions de operator[] ont été implémentées, avec un retour correct de références. Si nécessaire, la méthode at() avec vérification des limites a été ajoutée.
Avantages :
Inconvénients :
operator[] peut toujours entraîner une erreur de débordement