Эта программа теперь отображает такие результаты (в предположении, что на приглашение "Введите строку: " вы введете "Привет").

Введите строку: Привет

Освобождение 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, оператор "[]" можно использовать слева от оператора присваивания, что позволит модифицировать любой элемент массива. (Конечно же, его по-прежнему можно использовать и справа от оператора присваивания.)

Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги