Эта программа теперь отображает такие результаты (в предположении, что на приглашение "Введите строку: "
вы введете "Привет").
Введите строку: Привет
Освобождение s-памяти.
Освобождение s-памяти.
Освобождение s-памяти.
Привет
Освобождение s-памяти.
Как видите, эта программа теперь работает корректно. Вы должны понимать, почему выводится каждое из сообщений "Освобождение s-памяти. "
. (Подсказка: одно из них вызвано инструкцией delete в теле операторной функции operator=().)Перегрузка оператора индексации массивов ([])
В дополнение к традиционным операторам C++ позволяет перегружать и более "экзотические", например, оператор индексации массивов ([]
). В C++ (с точки зрения механизма перегрузки) оператор "[]" считается бинарным. Его можно перегружать только для класса и только с использованием функции-члена. Вот как выглядит общий формат операторной функции-члена operator[]().
тип имя_класса::operator[](int индекс)
{
// ...
}
Оператор "[]" перегружается как бинарный оператор.
Формально параметр индекс
необязательно должен иметь тип int, но операторные функции operator[]() обычно используются для обеспечения индексации массивов, поэтому в общем случае в качестве аргумента этой функции передается целочисленное значение.Предположим, у нас определен объект ob
, тогда выражение
ob[3]
преобразуется в следующий вызов операторной функции operator[]()
:
ob.operator[](3)
Другими словами, значение выражения, заданного в операторе индексации, передается операторной функции operator[]()
в качестве явно заданного аргумента. При этом указатель this будет указывать на объект ob, т.е. объект, который генерирует вызов этой функции.В следующей программе в классе atype
объявляется массив для хранения трех int-значений. Его конструктор инициализирует каждый член этого массива. Перегруженная операторная функция operator[]() возвращает значение элемента, заданного его параметром.
// Перегрузка оператора индексации массивов
#include
using namespace std;
const int SIZE = 3;
class atype {
int a[SIZE];
public:
atype() {
register int i;
for(i=0; i
}
int operator[](int i) {return a[i];}
};
int main()
{
atype ob;
cout << ob[2]; // отображает число 2
return 0;
}
Здесь функция operator[]()
возвращает значение i-го элемента массива a. Таким образом, выражение ob[2] возвращает число 2, которое отображается инструкцией cout. Инициализация массива a с помощью конструктора (в этой и следующей программах) выполняется лишь в иллюстративных целях.Можно разработать операторную функцию operator[]()
так, чтобы оператор "[]" можно было использовать как слева, так и справа от оператора присваивания. Для этого достаточно указать, что значение, возвращаемое операторной функцией operator[](), является ссылкой. Эта возможность демонстрируется в следующей программе.
// Возврат ссылки из операторной функции operator()[].
#include
using namespace std;
const int SIZE = 3;
class atype {
int a[SIZE];
public:
atype() {
register int i;
for(i=0; i
}
int &operator[](int i) {return a[i];}
};
int main()
{
atype ob;
cout << ob[2]; // Отображается число 2.
cout <<" ";
ob[2] = 25; // Оператор "[]" стоит слева от оператора "=".
cout << ob[2]; // Теперь отображается число 25.
return 0;
}
При выполнении эта программа генерирует такие результаты.
2 25
Поскольку функция operator[]()
теперь возвращает ссылку на элемент массива, индексируемый параметром i, оператор "[]" можно использовать слева от оператора присваивания, что позволит модифицировать любой элемент массива. (Конечно же, его по-прежнему можно использовать и справа от оператора присваивания.)