Перегрузка оператора: функция-член против функции-не-члена?


Я прочитал, что перегруженный оператор, объявленный как функция-член, асимметричен, потому что он может иметь только один параметр, а другой параметр, передаваемый автоматически, является указателем "this". Поэтому не существует стандарта для их сравнения. С другой стороны, перегруженный оператор, объявленный как друг, симметричен, потому что мы передаем два аргумента одного типа и, следовательно, их можно сравнить. Мой вопрос заключается в том, что когда я все еще могу сравнить значение lvalue указателя со ссылкой, почему предпочтительны друзья? (использование асимметричной версии дает те же результаты, что и симметричная) Почему алгоритмы STL используют только симметричные версии?

2 89

2 ответа:

если вы определяете перегруженную функцию оператора как функцию-член, то компилятор переводит выражения типа s1 + s2 на s1.operator+(s2). это означает, что оператор перегруженной функции-члена вызывается на первом операнде. вот как работают функции-члены!

но что, если первый операнд не является классом? существует серьезная проблема, если мы хотим перегрузить оператор, где первый операнд не является типом класса, а скажем double. так вы не можете писать так 10.0 + s2. Однако вы можете написать оператор перегруженной функции-члена для таких выражений, как s1 + 10.0.

чтобы решить эту заказ проблема, мы определяем перегруженную функцию оператора как friend если ему нужен доступ private членов. сделать friend только тогда, когда он должен получить доступ к закрытым членам. в противном случае просто сделать это не-друг, не являющихся членами до улучшение инкапсуляция!

class Sample
{
 public:
    Sample operator + (const Sample& op2); //works with s1 + s2
    Sample operator + (double op2); //works with s1 + 10.0

   //Make it `friend` only when it needs to access private members. 
   //Otherwise simply make it **non-friend non-member** function.
    friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2
}

читать это :
небольшая проблема упорядочения в операндах
Как Функции, Не Являющиеся Членами, Улучшают Инкапсуляцию

это не обязательно различие между friend оператор перегружает и оператор функции-члена перегружает, как это между глобальные перегрузки оператора и перегрузки оператора функции-члена.

одна из причин предпочесть глобальные перегрузка оператора-это если вы хотите разрешить выражения, в которых тип класса отображается на право ручная сторона двоичного оператора. Например:

Foo f = 100;
int x = 10;
cout << x + f;

это работает только если есть перегрузка глобального оператора для

Foo operator + (int x, const Foo& f);

обратите внимание, что перегрузка глобального оператора не обязательно должна быть