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