Перегрузка операторов дает возможность добавлять к встроенным типам данных в С++ новые типы. В зависимости от назначения перегрузка операторов объявляется так же, как и обычная дружественная функция или функция-член класса.
class ZZ {
public:
friend ZZ operator+(ZZa, ZZb);
friend ZZ operator-(ZZa, ZZb);
friend ZZ operator*(ZZa, ZZb);
friend ZZ operator/(ZZa, ZZb);
};
Имена функций — operator/, operator*, operator-, operator+ состоят из ключевого слова operator и символа операции.
Список операций, которые могут быть пререгружены
* / + — % ^ & :
— ! , = < > <= >=
++ — << >> == != && ||
*= /* %= ^= &= |= += -=
<<= >>= -> ->* [] () new delete
operator+(a, b); аналогично a + b;
выполняется одно и тоже действие и генерируют одинаковый код. Перегрузка не вносит в С++ ничего нового, только лишь позволяет использовать в выражениях объекты классов вместо того, чтобы передавать их в функции.
// Программа 4 Пример перегрузки операторов с помощью
// дружественных функций
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
class TStrOp {
private:
char val[12];
public:
TStrOp() { val[0]=0; }
TStrOp(const char* s);
long GetVal(void) { return atol(val);}
friend long operator+(TStrOp a, TStrOp b);
friend long operator-(TStrOp a, TStrOp b);
};
void main()
{
TStrOp a = "1234";
TStrOp b = "4321";
cout << endl << "value of a == " << a.GetVal();
cout << endl << "value of b == " << b.GetVal();
cout << endl << " a + b + 6 == " << ( a + b + 6 );
cout << endl << " a — b + 10 == " << ( a — b + 10 )
<< endl;
}
TStrOp::TStrOp(const char* s)
{
strncpy(val, s, 11);
val[11]=0;
}
long operator+(TStrOp a, TStrOp b)
{
return (atol(a.val) + atol(b.val));
}
long operator-(TStrOp a, TStrOp b)
{
return (atol(a.val) — atol(b.val));
}
Перегруженные функции могут быть членами класса. Отличие состоит только в определении функции, где указыва-ется членом какого класса является данная перегружаемая функция.
class TStrOp {
private:
char val[12];
public:
TStrOp() { val[0]=0; }
TStrOp(const char* s);
long GetVal(void) { return atol(val);}
long operator+(TStrOp a, TStrOp b);
long operator-(TStrOp a, TStrOp b);
};
long TStrOp::operator+(TStrOp b)
{
return (atol(val) + atol(b.val));
}
long TStrOp::operator-(TStrOp b)
{
return (atol(val) — atol(b.val));
}
4.3.1. Перегрузка унарных операторов
Унарные операторы могут быть объявлены как функции-члены, не имеющие аргументов, так и дружественными функ-циями.
long operator -(void) //Унарный минус
{ return -atol(val); }
friend long operator-(TStrOp a)
{ return -atol(a.val); }
4.3.2. Оператор индексирования массива.
Можно перегрузить оператор индексирования массива [] для реализации доступа к данным-членам класса, подобного доступу к элементу массива, даже если эти данные имеют вид отдельных членов класса или связного списка.
// Программа 5 Пример перегрузки индексирования
#include <iostream.h>
class Psevdoarray {
private:
int val0;
int val1;
int val2;
int val3;
public:
Psevdoarray( int v0, int v1, int v2, int v3)
{ val0 = v0; val1 = v1; val2 = v2; val3 = v3;}
int GetInt(unsigned i);
int operator[] (unsigned i);
};
void main()
{
Psevdoarray pa(10, 20, 30,40);
for( int i=0; i<=3; i++)
cout << "pa[" << i << "] ==" << pa[i] << endl;
}
int Psevdoarray::GetInt(unsigned i)
{
switch (i) {
case 0: return val0;
case 1: return val1;
case 2: return val2;
case 3: return val3;
default: return val0;
}
}
int Psevdoarray::operator[](unsigned i)
{
return GetInt(i);
}
4.3.3. Оператор вызова функции
Перегрузка вызова функции operator() делает объект класса похожим на функцию, которую можно вызывать. Пере-груженная функция может возвращать значения заданных типов или ничего не возвращать. Кроме того в ней могут быть объявлены параметры.
class X {
int x;
public:
int operator()(void);
X(int n) { x=n; }
};
int X::operator()(void)
{
return x;
}
main()
{
X object = 100;
int g == object(); //выглядит как вызов функции
cout << q; //на самом деле object.operator()();
return 0;
}
