перегрузка оператора (друг и функция членства)

Каково различие между перегрузкой оператора с помощью friend ключевое слово и как функция членства в классе?

Кроме того, каково различие в случае какой-либо перегрузки унарного оператора (т.е. как друг по сравнению с как функция членства)?

9
задан Foggzie 17 July 2015 в 21:51
поделиться

4 ответа

Джейкоб прав... friend функция, объявленная внутри класса, имеет доступ к этому классу, но она вообще не внутри класса, и все остальные имеют к ней доступ.

Для перегрузки оператора, который не является членом класса (также называется свободная функция, она может быть другом, а может и нет), аргументы те же, что и операнды. Для той, которая является членом класса, первым операндом является "неявный аргумент", который становится this.

Неявный аргумент отличается от первого аргумента свободной функции несколькими способами:

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

Ситуация одинакова для унарных, бинарных или n-арных (в случае operator()).

Привилегия членов мутации: Операторы, изменяющие первый операнд (например, +=, =, префикс ++) должны быть реализованы как функции-члены, и должны реализовывать исключительно потроха всех перегрузок. Постфикс ++ - гражданин второго сорта; он реализуется как Obj ret = *this; ++ this; return ret;. Заметим, что это иногда распространяется на копирующие конструкторы, которые могут содержать *this = initializer.

Правило свободы для коммутаторов: Только коммутативные операторы (например, /) должны быть свободными функциями; все остальные операторы (например, унарное что угодно) должны быть членами. Коммутативные операторы по своей природе создают копию объекта; они реализуются как Obj ret = lhs; ret @= rhs; return ret; где @ - коммутативный оператор, а lhs и rhs - аргументы левой и правой сторон, соответственно.

Золотое правило дружбы в C++: Избегайте дружбы. friend загрязняет семантику конструкции. Следствие перегрузки: Перегрузка проста, если вы следуете вышеприведенным правилам, тогда friend безвреден. friendвключение шаблонных определений перегрузки позволяет поместить их внутрь class {скобок.

Обратите внимание, что некоторые операторы не могут быть свободными функциями: =, ->, [], и (), потому что стандарт специально говорит об этом в разделе 13.5. Думаю, это все... Я думал, что унарные & и * тоже, но, видимо, я ошибался. Однако их следует всегда перегружать как члены, и только после тщательного обдумывания!

12
ответ дан 4 December 2019 в 12:17
поделиться

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

Так, например, мы создаем класс BigInt. И мы создаем оператор функции-члена +, чтобы взять правый оператор BigInt.

Теперь допустим, что у BigInt есть конструктор, который принимает обычный тип int. Этот конструктор НЕ является явным (явное ключевое слово) и принимает один параметр. Это означает, что C ++ может неявно преобразовывать int в BigInt.

Когда у нас есть эти вещи, мы можем сделать это:

BigInt foo (5); BigInt bar; bar = foo + 5;

Но мы НЕ МОЖЕМ сделать это:

BigInt foo (5) BigInt bar; bar = 5 + foo;

Однако, если мы использовали функцию друга вместо функции-члена, тогда обе будут работать.

1
ответ дан 4 December 2019 в 12:17
поделиться

Функции-члены могут вызываться для rvalue, тогда как свободные функции, принимающие ссылки на неконстантные, не могут быть вызваны с rvalue. Например, ++ function_returning_iterator_by_value () компилируется, только если вы реализуете operator ++ как член.

0
ответ дан 4 December 2019 в 12:17
поделиться

Разница в том, что функция friended фактически находится в глобальной области видимости, поэтому вам не нужно быть экземпляром класса, чтобы иметь к ней доступ.

3
ответ дан 4 December 2019 в 12:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: