Справочник по C/C++
Перегрузка операторов

Ключевое слово operator используется для создания перегруженных функций-операторов. Функции-операторы существуют в двух ипостасях: члена и не члена.

Общая форма записи функции-оператора как члена имеет следующий вид.

тип_возврата имя_класса :: operator # (список_параметров)
{
	//...
}
Здесь тип_возврата означает тип значения, возвращаемого функцией, имя_класса — имя класса, для которого перегружается этот оператор, а элемент # — сам перегружаемый оператор. При перегрузке унарного оператора список_параметров пуст. Операнд передаётся неявным образом в указателе this. При перегрузке бинарного оператора список_параметров задаёт операнд справа от оператора. Операнд слева передаётся неявным образом в указателе this. Например, следующий код создаёт тип данных "вектор".
class vector{
	int x, y, z;
public:
	vector operator+ (vector t);
	vector operator= (vectort);
	vector operator++ (void);
	void show (void);
	void assign (int mx, int my, int mz);
}
vector vector :: operator+ (vector t)
{
	vector temp;
	temp.x = x + t.x;
	temp.y = y + t.y;
	temp.z = z + t.z;
	return temp;
}
vector vector :: operator= (vector t)
{
	x = t.x;
	y = t.y;
	z = t.z;
	return *this;
}
vector vector :: operator++ (void)
{
	x++;
	y++;
	z++
	return *this;
}
void vector :: show (void)
{
	cout << x << ",";
	cout << y << ",";
	cout << z << " \n";
}
void vector :: assign (int mx, int my, int mz)
{
	x = mx;
	y = my;
	z = mz;
}

main (void)
{
	vector a, b, c;
		a.assign (1, 2, 3);
	b.assign (10, 10, 10);
	a.show();
	b.show();
	
	c = a + b;
	c.show();
	c = a + b + c;
	c.show();
	
	c++;
	c.show();
}

Что касается функций-не членов, функция-оператор имеет следующую форму.

тип_возврата operator # (список_параметров)
{
	//...
}
Здесь список_операторов содержит один параметр при перегрузке унарного оператора. При перегрузке бинарного оператора операнд слева передаётся в первом параметре, а операнд справа — во втором параметре.

Поскольку нельзя перегружать операторы для встроенных типов, можно создать, с помощью ключевого слова typedef, новый тип который будет аналогом необходимого. Например для сравнения переменных встроенного типа char, мы напишем следующее.

typedef struct { char *str} Item;
int operator < (const Item& a, const Item& b)
{
	return strcmp (a.str, b.str) < 0;
}

Применительно к перегрузке операторов действует несколько ограничений. Нельзя изменять приоритет оператора. Нельзя также изменять количество операндов, требуемых оператором. Нельзя изменять значение оператора, связанного со встроенными типами данных языка C++. Нельзя создавать новый оператор. Операторы препроцессора # и ## не могут быть перегружены. Нельзя перегружать следующие операторы: . :: .* ?

Дружественные функции-операторы

Отличие дружественных функций-операторов от обычных функций-операторов, членов класса, состоит в том что для них не используется указатель this При объявлении дружественной функции оператора должны передаваться два аргумента для бинарных операторов и один для унарных операций. Например.

class vrctor{
	int x, y, z;
public:
	friend vector operator+ (vector t1, vector t2);
}
vector operator+ (vector t1, vector t2)
{
	vector tmp;
	tmp.x = t1.x + t2.x;
	tmp.y = t1.x + t2.y;
	tmp.z = t1.x + t2.z;
	return temp;
}

Перегрузка операции индексации []

Операция индексации рассматривается как бинарная операция, где первый оператор — объект класса, а второй — целочисленный индекс. Например.

class vector{
	int v[3];
public:
	int& operator[] (int i);
}
int& vector :: operator[] (int i)
{
	return  v[i];
}
//...
v[0] = 100;	//ссылаемся на приватный член с помощью перегруженного оператора []

Перегрузка операции преобразования типа ()

Операции преобразования типов можно также перегружать, при этом в виде оператора указывается тип данных. Например.

struct Item{
	int item;
	Item (int t){
		item = t;
	}
	operator int(){
		return item;
	}
};
Item t (11);
cout << (int)t;	//Напечатает число 11