Одно из достоинств перегрузки оператора "[]" состоит в том, что с его помощью мы можем обеспечить средство реализации безопасной индексации массивов. Как вы знаете, в C++ возможен выход за границы массива во время выполнения программы без Соответствующего уведомления (т.е. без генерирования сообщения о динамической ошибке). Но если создать класс, который содержит массив, и разрешить доступ к этому массиву только через перегруженный оператор индексации "[]", то возможен перехват индекса, значение которого вышло за дозволенные пределы. Например, следующая программа (в основу которой положен код предыдущей) оснащена средством контроля попадания в допустимый интервал.

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

#include

#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);

};

// Обеспечение контроля попадания в допустимый интервал для класса 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

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)

{

 three_d temp;

 temp.x = x + a;

 temp.у = у + b;

 temp.z = z + c;

 return temp;

}

// Отображение координат x, y, z.

void three_d::show()

{

 cout << x << ", ";

 cout << у << ", ";

 cout << z << "\n";

}

int main()

{

 three_d ob1(1, 2, 3), ob2;

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

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

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