Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
недостающая теория.doc
Скачиваний:
8
Добавлен:
22.09.2019
Размер:
619.01 Кб
Скачать

5.2.5. Перегрузка оператора []

Как было отмечено выше, функция operator может быть с успехом использована для доопределения операторов С++ (в основном арифметические, логические и операторы отношения). В то же время в С++ существуют некоторые операторы, не входящие в число перечисленных, но которые полезно перегружать. К ним относится оператор []. Его необходимо перегружать с помощью компоненты-функции, использование friend-функции запрещено. Общая форма функции operator[]() имеет вид

тип_возвр_значения имя_класса::operator [](int i)

{ тело функции}

Параметр функции необязательно должен иметь тип int , но он использован, так как operator[] в основном применяется для индексации. Рассмотрим пример программы с использованием перегрузки операции []:

#include <iostream>

using namespace std;

class massiv

{ float f[3];

public:

massiv(float i,float j,float k){f[0]=i; f[1]=j; f[2]=k;}

float operator[](int i)

{ return f[i];} // перегрузка оператора []

};

int main()

{ massiv ff(1,2,3);

double f;

int i;

cout << "введите номер индекса ";

cin >> i;

cout <<"f["<< i <<" ]= " << ff[i] << endl;

return 0;

}

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

#include <iostream>

using namespace std;

class massiv

{ float f[3];

public:

massiv(float i,float j,float k){f[0]=i; f[1]=j; f[2]=k;}

float &operator[](int i) // перегрузка оператора []

{ if(i<0 || i>2) // проверка на выход за границы массива

{ cout << “Выход за пределы массива”<<endl;

exit(1);

}

return f[i];

}

};

int main()

{ massiv ff(1,2,3);

int i;

cout << "введите номер индекса ";

cin >> i;

cout <<"f["<< i <<" ]= " << ff[i] << endl;

ff[i]=5; // если функция operator не возвращает ссылку,то компиля-

// тор выдает ошибку =' : left operand must be l-value

cout <<"f["<< i <<" ]= " << ff[i] << endl;

return 0;

}

Рассмотрим случай, когда функция operator возвращает не ссылку, а указатель на модифицируемое значение. Внесем некоторые изменения в рассмотренную выше программу.

class massiv

{ float f[3];

public:

. . .

float *operator[](int i) // перегрузка оператора []

{ . . .

return &f[i];

}

};

int main()

{ massiv ff(1,2,3);

. . .

*ff[i]=5; // функция operator возвращает указатель

cout <<"f["<< i <<" ]= " << *ff[i] << endl;

return 0;

}

В приведенном примере создается ложное впечатление, что ff является вектором указателей. Поэтому использование ссылки представляется более предпочтительным.

Приведем еще один пример программы, использующей перегрузку operator[].

// перегрузка функции operator[] на примере вычисления n!

#include <iostream>

using namespace std;

#include "values.h" // для определения константы MAXLONG

class fact

{ long l;

public:

long operator[](int); // перегрузка оператора []

};

long fact::operator[](int n)

{ long l;

for (int i=0; i<=n; i++) //выбор буквы из уменьшаемой строки

if(l>MAXLONG/i)

cerr<<"ОШИБКА факториал числа "<<n<<" больше "<<MAXLONG;

else l*=i;

return l;

}

int main()

{ fact f;

int i,k;

cout << "введите число k для нахождения факториала"

cin >> k;

for (i=1; i<=k; i++)

cout << i <<"! = " << f[i] << endl;

return 0;

}