Выбрать главу

// Пример организации безопасного массива.

#include <iostream>

#include <cstdlib>

using namespace std;

const int SIZE = 3;

class atype {

  int a[SIZE];

 public:

  atype() {

   register int i;

   for(i=0; i<SIZE; i++) a[i] = i;

  }

 int &operator[] (int i);

};

// Обеспечение контроля попадания в допустимый интервал для класса atype.

int &atype:: operator [](int i)

{

 if(i<0 || i>SIZE-1) {

  cout << "\n Значение индекса ";

  cout << i << " выходит за границы массива. \n";

  exit(1);

 }

 return a[i];

}

int main()

{

 atype ob;

 cout << ob[2]; // Отображается число 2.

 cout << " ";

 ob[2] =25; // Оператор "[]" стоит в левой части.

 cout << ob[2]; // Отображается число 25.

 ob[3] = 44; // Генерируется ошибка времени выполнения.

 // поскольку значение 3 выходит за границы массива.

 return 0;

}

При выполнении эта программа выводит такие результаты.

2 25

Значение индекса 3 выходит за границы массива.

При выполнении инструкции

ob[3] = 44;

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

Перегрузка оператора "()"

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

int operator()(float f, char *p);

И если в программе создается объект ob этого класса, то инструкция

ob (99.57, "перегрузка");

преобразуется в следующий вызов операторной функции operator():

operator() (99.57, "перегрузка");

В общем случае при перегрузке оператора "()" определяются параметры, которые необходимо передать функции operator(). При использовании оператора "()" в программе задаваемые при этом аргументы копируются в эти параметры. Как всегда, объект, который генерирует вызов операторной функции (ob в данном примере), адресуется указателем this.

Рассмотрим пример перегрузки оператора "()" для класса three_d. Здесь создается новый объект класса three_d, координаты которого представляют собой результаты суммирования соответствующих значений координат вызывающего объекта и значений, передаваемых в качестве аргументов.

// Демонстрация перегрузки оператора "()".

#include <iostream>

using namespace std;

class three_d {

  int x, y, z; // 3-мерные координаты

 public:

  three_d() { x = у = z = 0; }

  three_d(int i, int j, int k) {x = i; у = j; z = k; }

  three_d operator()(int a, int b, int c);

  void show();

};

// Перегрузка оператора "()".

three_d three_d::operator()(int a, int b, int c)