В отличие от функций-членов, функции-не члены (в том числе и "друзья" класса) не получают указатель this и, следовательно, не имеют доступа к объекту, для которого они были вызваны. Но мы знаем, что "дружественной" операторной функции операнд передается явным образом. Поэтому попытка создать операторную функцию-"друга" operator++() в таком виде успехом не увенчается.

// ЭТОТ ВАРИАНТ РАБОТАТЬ НЕ БУДЕТ

three_d operator++(three_d op1)

{

 op1.x++;

 op1.y++;

 op1.z++;

 return op1;

}

Эта функция неработоспособна, поскольку только копия объекта, активизировавшего вызов функции operator++(), передается функции через параметр op1. Таким образом, изменения в теле функции operator++() не повлияют на вызывающий объект, они изменяют только локальный параметр.

Если вы хотите для перегрузки операторов инкремента или декремента использовать функцию-"друга", необходимо передать ей объект по ссылке. Поскольку ссылочный параметр представляет собой неявный указатель на аргумент, то изменения, внесенные в параметр, повлияют и на аргумент. Применение ссылочного параметра позволяет функции успешно инкрементировать или декрементировать объект, используемый в качестве операнда.

Если для перегрузки операторов инкремента или декремента используется функция-"друг", ее префиксная форма принимает один параметр (который и является операндом), а постфиксная форма — два параметра (вторым является целочисленное значение, которое не используется).

Ниже приведен полный код программы обработки трехмерных координат, в которой используется операторная функция-"друг" operator++(). Обратите внимание на то, что перегруженными являются как префиксная, так и постфиксная формы операторов инкремента.

// В этой программе используются перегруженные

// операторные функции-"друзья" operator++() .

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

  friend three_d operator+(three_d op1, three_d op2);

  three_d operator=(three_d op2);

  // Эти функции для перегрузки

  // оператора "++" используют ссылочные параметры.

  friend three_d operator++(three_d &op1);

  friend three_d operator++(three_d &op1, int notused);

  void show();

};

// Теперь это функция-"друг".

three_d operator+(three_d op1, three_d op2)

{

 three_d temp;

 temp.x = op1.x + op2.x;

 temp.у = op1.у + op2.y;

 temp.z = op1.z + op2.z;

 return temp;

}

// Перегрузка оператора "=".

three_d three_d::operator=(three_d op2)

{

 x = op2.x;

 у = op2.y;

 z = op2.z;

 return *this;

}

/* Перегрузка префиксной версии оператора "++" с использованием функции-"друга". Для этого необходимо использование ссылочного параметра.

*/

 three_d operator++(three_d &op1)

{

 op1.х++;

 op1.у++;

 op1.z++;

 return op1;

}

/* Перегрузка постфиксной версии оператора "++" с использованием функции-"друга". Для этого необходимо использование ссылочного параметра.

*/

 three_d operator++(three_d &op1, int notused)

{

 three_d temp = op1;

 op1.x++;

 op1.у++;

 op1.z++;

 return temp;

}

// Отображение координат X, Y, Z.

void three_d:: show()

{

 cout << x << ", ";

 cout << у << ", ";

 cout << z << "\n";

}

int main()

{

 three_d a(1, 2, 3), b(10, 10, 10), c;

 a.show();

 b.show();

 с = a + b; // сложение объектов а и b

 c.show();

 c=a+b+c; // сложение объектов a, b и с

 с.show();

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

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

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