Оператор доступа по индексу operator[] — это перегружаемый оператор в C++ для обеспечения синтаксиса индексирования объектов пользовательских контейнеров (например, как массивов).
История вопроса:
В языке C, а позже и в C++, оператор [] позволял быстро и удобно обращаться к элементам массива по индексу. Однако с ростом популярности контейнерных классов возникла задача перенести тот же синтаксис на пользовательские типы данных.
Проблема:
Правильное проектирование операторов доступа по индексу сопряжено с вопросами константности, безопасности выхода за пределы (out-of-bounds), выбора возвращаемого значения и гарантии валидности ссылки или указателя.
Решение:
В C++ можно перегружать operator[] для классов, чтобы позволять доступ к элементам по индексу и реализовать для них "поведение как у массива". Нужно реализовать обе версии оператора — обычную (для неконстантных объектов) и константную (для константных объектов).
Пример кода:
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
Ключевые особенности:
.at() в стандартных контейнерах)Обязателен ли возврат ссылки из operator[]?
Нет — но если возвращать значение, синтаксис arr[i] = x; работать не будет (вы будете копировать вместо присваивать). Чтобы поддержать привычную семантику контейнера, обычно возвращают reference. Если возвращать значение, то записи в элемент не получится:
int operator[](size_t idx); // arr[2] = 10; не скомпилируется
Должен ли operator[] проверять границы?
Стандарт не требует этого. Классический operator[] (как в std::vector) НЕ делает таких проверок. Для проверок стандартные контейнеры вводят отдельный метод .at(), который бросает исключение при выходе за пределы диапазона индексирования.
Может ли operator[] быть константным методом?
Нет — если вы возвращаете неконстантную ссылку. Однако перегружать operator[] нужно и для константных, и для неконстантных объектов, чтобы контейнер работал интуитивно и безопасно.
Молодой разработчик реализовал только неконстантную версию operator[], возвращающую по значению. В итоге к контейнеру нельзя было обращаться по const-ссылке, и любые попытки записи работали странно — значения не сохранялись.
Плюсы:
Минусы:
В контейнере MyArray реализованы обе версии operator[], с корректным возвратом ссылок. При необходимости добавлен метод at() с проверкой границ.
Плюсы:
Минусы: