Джейкоб прав: функция, объявленная в классе friend
, имеет доступ к этому классу, но вообще не находится внутри класса, и все остальные имеют к нему доступ.
Для перегрузки оператора, которая не является членом класса (также называемой свободной функцией , она может быть другом или нет), аргументы совпадают с операндами. Для того, кто является членом класса, первый операнд является «неявным аргументом», который становится this
.
Неявный аргумент отличается от первого аргумента свободной функцией несколькими способами:
- Его тип - ссылка на класс, тогда как свободная функция может объявить любой тип для своего первого аргумента.
- Не участвует в неявном преобразовании типов. (Это не будет временная инициализация конструктором преобразования.)
- Он участвует в виртуальном разрешении переопределения. (Перегрузка
virtual
будет выбрана динамическим типом первого операнда, что невозможно для свободных функций без дополнительного кода.)
Ситуация такая же для унарных, двоичных или n-арных (в случае operator()
).
Члены привилегии мутации: Операторы, которые изменяют первый операнд (например, +=
, =
, префикс ++
), должны быть реализованы в качестве функций-членов и должны реализовывать только внутренности всех перегрузки. Постфикс ++
- гражданин второго сорта; это реализовано как Obj ret = *this; ++ this; return ret;
. Обратите внимание, что это иногда распространяется на конструкторы копирования, которые могут содержать *this = initializer
.
Правило свободы для пассажиров: Только коммутативные операторы (например, /
) должны быть свободными функциями; все остальные операторы (например, унарные все) должны быть членами. Коммутативные операторы по своей сути делают копию объекта; они реализованы как Obj ret = lhs; ret @= rhs; return ret;
, где @
- коммутативный оператор, а lhs
и rhs
- аргументы левой и правой стороны соответственно.
Золотое правило дружбы на С ++: Избегайте дружбы. friend
загрязняет семантику дизайна. Следствие перегрузки: Перегрузка проста, если вы следуете приведенным выше правилам, тогда friend
безвреден. friend
Определение определения перегрузки шаблонов позволяет размещать их в скобках class {
.
Обратите внимание, что некоторые операторы не могут быть свободными функциями: =
, ->
, []
и ()
, потому что в стандарте это специально указано в разделе 13.5. Я думаю, что это все ... я думал, что унарные &
и *
тоже, но я был явно неправ. Они должны всегда перегружаться как члены, и только после тщательного обдумывания!