Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции C++.doc
Скачиваний:
7
Добавлен:
01.05.2025
Размер:
1.44 Mб
Скачать

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

Функция-оператор может быть другом класса, а не только его членом. Как было показано ранее в этой главе, поскольку функции-друзья не являются членами класса, они не могут иметь неявный аргумент this. Поэтому при использовании дружественной функции-оператора оба операнда пе­редаются функции при перегрузке бинарных операторов, а при перегрузке унарных операторов передается один операнд. Следующие операторы не могут использовать перегрузку с помощью функций-друзей: =, (), [], и ->. Остальные операторы могут быть перегружены как с помощью функций-членов, так с помощью функций-друзей. В качестве примера ниже рассматривается мо­дифицированная версия предыдущей программы, в которой оператор + перегружен с помощью дружественной функции:

#include <iostream.h>

class point

{

int x, у, z; // трехмерные координаты

public:

friend point operator+(point p1, point p2);

point operator=(point p2); // p1 подразумевается

point operator++(); // p1 также подразумевается

void show();

void set(int mx, int my, int mz);

};

point operator+(point p1, point p2)

{

point temp;

temp.x = p1.x + p2.x; temp.у = p1.у + p2.y; temp.z = p1.z + p2.z;

return temp; }

//остальные функции остались прежними

int main()

{

point a, b, c;

a.set(1, 2, 3); b.set(10, 10, 10);

a.show(); b.show();

с = a+b; // сложение a и b

с.show();

с = a+b+c; // сложение a, b и c

с.show();

return 0;

}

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

Во многих случаях использование функций-друзей вместо функций-членов не дает выигрыша при перегрузке операторов. Однако имеется одна ситуация, в которой необходимо использо­вать дружественные функции. Как известно, указатель на объект, вызывающий функцию-опера­тор, передается в указателе this. В случае бинарных операторов левый объект вызывает эту фун­кцию. Такой способ работает до тех пор, пока левый объект определяет заданную операцию. Предположим, что для объекта A определены операции присваивания и сложения, так что следующий код

A = A + 10;

является корректным. Поскольку объект A находится с левой стороны оператора +, то он вызы­вает функцию-оператор, перегружающую операцию сложения, которая по предположению способна добавить целое число к определенному элементу объекта A. Однако следующая инструкция не является корректной:

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

Причина, по которой эта инструкция не будет выполняться, заключена в том, что слева от опера­тора + теперь стоит целое число, являющееся встроенным типом и не имеющее функции-члена, кото­рая могла бы осуществить сложение с объектом A.

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