Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекции / Лекция 5-6_n — копия.docx
Скачиваний:
0
Добавлен:
11.02.2026
Размер:
144.59 Кб
Скачать

Int main (){

IntArray array;

array[4] = 5; // хорошо: вызывается неконстантная версия //operator[]()

std::cout << array[4];

const IntArray carray;

carray[4] = 5; // ошибка компиляции: вызывается константная //версия operator[](), которая возвращает константную ссылку. //Выполнять операцию присваивания нельзя

std::cout << carray[4];

return 0;

}

Строку carray[4] = 5; нужно закомментировать и программа скомпилируется (это проверка на изменение данных константных объектов — изменять данные нельзя, можно только выводить).

Проверка ошибок

Еще одним преимуществом перегрузки операции индексации является то, что мы можем выполнять проверку передаваемых значений индекса.

При прямом доступе к элементам массива (через геттеры и сеттеры), оператор индекса не проверяет, является ли индекс корректным. Например, компилятор не будет жаловаться на следующий код:

int array[7];

array[9] = 4; // индекс 9 является некорректным (вне допустимого //диапазона)!

Однако, если мы знаем длину нашего массива, мы можем выполнять проверку передаваемого индекса на корректность в функции перегрузки операции []:

#include <cassert> // для assert ()

class IntArray {

private:

Int m_array[10];

public:

Int& operator [] (const int index);

};

Int& IntArray::operator[] (const int index) {

assert(index >= 0 && index < 10);

return m_array[index];

}

В примере, приведенном выше, мы использовали вызов функции assert (которая определена в заголовочном файле cassert) для проверки диапазона index.

Если выражение внутри assert принимает значение false (т.е. пользователь ввел некорректный индекс), то программа немедленно завершится с выводом сообщения об ошибке, что лучше, нежели альтернативный вариант — повреждение памяти.

Это самый распространенный способ проверки ошибок с использованием функций перегрузки.

Указатели на объекты и перегруженный оператор []

Если вы попытаетесь вызвать operator [] () для указателя на объект, то C++ предположит, что вы пытаетесь индексировать массив.

Рассмотрим следующий пример:

#include <cassert> // для assert ()

class IntArray {

private:

int m_array [10];

public:

int& operator [] (const int index);

};

int& IntArray::operator [] (const int index) {

assert (index >= 0 && index < 10);

return m_array[index];

}

int main () {

IntArray *array = new IntArray;

array [4] = 5; // ошибка

delete array;

return 0;

}

Дело в том, что указатель указывает на адрес памяти, а не на значение. Поэтому сначала указатель нужно разыменовать, а затем уже использовать оператор []:

int main () {

IntArray *array = new IntArray;

(*array) [4] = 5; // сначала разыменовываем указатель для //получения объекта array, а затем вызываем operator []

delete array;

return 0;

}

Здесь очень легко наделать ошибок. Не используйте указатели на объекты, если это не является обязательным.

Передаваемый аргумент не обязательно должен быть целым числом

Как упоминалось выше, C++ передает в функцию перегрузки то, что пользователь указал в квадратных скобках в качестве аргумента (в большинстве случаев, это целочисленное значение).

Однако это не является обязательным требованием и, на самом деле, вы можете определить функцию перегрузки так, чтобы ваш перегруженный оператор [] принимал значения любого типа, которого вы только пожелаете (double, string и т.д.).

Например:

#include <iostream>

#include <string>

class Something {

private:

public: