Выбрать главу

 с = b = а; // демонстрация множественного присваивания

 с.show();

 b.show();

 return 0;

}

Как видите, операторной функции operator+() теперь передаются два операнда. Левый операнд передается параметру op1, а правый — параметру ор2.

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

ob + 10; // будет работать

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

10 + ob; // не будет работать

Дело в том, что в этой инструкции объект, расположенный слева от оператора "+", представляет собой целое число, т.е. значение встроенного типа, для которого не определена ни одна операция, включающая целое число и объект классового типа.

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

#include <iostream>

using namespace std;

class CL {

 public:

  int count;

  CL operator=(CL obj);

  friend CL operator+(CL ob, int i);

  friend CL operator+(int i, CL ob);

};

CL CL::operator=(CL obj)

{

 count = obj.count;

 return *this;

}

// Эта версия обрабатывает аргументы

// объект + int-значение.

CL operator+(CL ob, int i)

{

 CL temp;

 temp.count = ob.count + i;

 return temp;

}

// Эта версия обрабатывает аргументы

// int-значение + объект.

CL operator+(int i, CL ob)

{

 CL temp;

 temp.count = ob.count + i;

 return temp;

}

int main()

{

 CL o;

 o.count = 10;

 cout << o.count << " "; // выводит число 10

 o=10+o; // сложение числа с объектом

 cout << o.count << " "; // выводит число 20

 o=o+12; // сложение объекта с числом

 cout << 0.count; // выводит число 32

 return 0;

}

Как видите, операторная функция operator+() перегружается дважды, позволяя тем самым предусмотреть два возможных способа участия целого числа и объекта типа CL в операции сложения.