Перегрузка операторов, для чего применяется, как осуществляется.
Функцией-операцией является каждая функция с именем operator #, где # представляет одну из следующих операций: new, delete, +, - , *, /, %, &, !, = , <, >, !=, (), [], -> и так далее.
Функции-операции могут быть одноместные (унарные) и двуместные (бинарные), при этом число операндов, приоритет и ассоциативность определенной функции, такие же, как в базовом языке.
Не разрешается перегружать следующие операции: *, sizeof, #, ##, ::, ?:.
Необходимо отметить, что специальные операции, а именно =, [], (), должны быть объявлены нестатическими составными функциями класса. Среди них особого внимания заслуживает операция присваивания, так как она не подлежит наследованию. Если пользователь не переопределяет самостоятельно операцию присваивания, то неявно создается предполагаемое присваивание
Class &Class::operator =(const Class &),
реализующее присваивание методом «поле – за – полем».
Функции-операции можно определять тремя способами: как составную функцию класса, как внешнюю функцию или как дружественную. В двух последних случаях функции передается хотя бы один параметр типа класс, указатель или ссылка на класс.
Перегрузка унарных операций
Унарная функция-операция, определяемая внутри класса, должна быть представлена с помощью нестатического метода без параметров. Рассмотрим пример простого класса.
class Test
{
int test;
public:
Test(){};
Test(int tst)
{
test = tst;
}
Test &operator ++()
{
++test;
return *this;
}
void Out()
{
cout << " Test: " << test << endl;
}
};
int main()
{
Test tst(200);
++tst;
tst.Out();
return 0;
}
Задание 13. Переопределите самостоятельно для данного класса унарную префиксную операцию как дружественную и как внешнюю.
Постфиксную унарную операцию отличают от префиксной путем передачи пустого параметра типа int, причем, если операция определяется как внешняя, этот параметр должен быть вторым. Длякласса Test:
Test operator ++(Test &tst, int)
{
tst.test++; return tst;
}
Обратите внимание на то, что для работы такой внешней функции, необходимо открыть доступ к полю test.
В продолжение задания 13, определите унарную постфиксную операцию как дружественную классу Test.
Перегрузка бинарных операций
Если бинарная операция определяется как нестатическая составная функция класса, то она должна иметь один параметр. Как правило это константная ссылка на объект определяемого класса. Данный параметр представляет собой правый операнд, а вызвавший объект считается левым операндом операции.
Для класса Test перегрузка операции сложения может быть представлена следующим образом:
Test Test:: operator+(const Test &tst)
{
return this->test+tst.test;
}
Определить самостоятельно перегрузку бинарных арифметических операций как внешнюю и дружественную функцию, с учетом того, что передавать им необходимо два параметра типа класс.
Бинарные арифметические операции всегда должны возвращать в качестве результата объект типа класс. Операции сравнения возвращают в качестве результата объект типа bool. Дополните класс Test операциями сравнения.
Важное место в определении класса является перегрузка операции присваивания. При определении данной операции следует руководствоваться следущими рассуждениями:
– эту операцию имеет смысл переопределять в том случае, если класс содержит поля, память под которые выделяется динамически;
– если программист не определял операцию самостоятельно, компилятор автоматически сгенерирует ее код как поэлементное копирование полей одного объекта в другой;
– операция не наследуется в производных классах;
– операцию можно определить только как составную функцию класса.
Разберите следующий пример, обратив особое внимание на операцию присваивания.
class Text
{
int Len;
char *Ref;
public:
Text()
{
Len = 0;
Ref = new char[Len];
};
Text(char *Str)
{
Ref = new char[Len=strlen(Str)+1];
strcpy_s(Ref,Len,Str);
}
~Text()
{
delete Ref;
}
Text &operator =(const Text &);
void Out()
{
cout << " Out text = " << Ref << endl;
}
};
Text &Text::operator =(const Text &Par)
{
if(this == &Par) return *this;
else
{
delete Ref;
Ref = new char[strlen(Par.Ref)+1];
strcpy_s(Ref,Len-1,Par.Ref);
}
return *this;
}
int main()
{
Text head("Text Text"), tail;
tail = head;
tail.Out();
return 0;
}
Операция strcpy_s, спецефичная для стандарта языка С, в последних версиях VC может работать некорректно.