Почему операторы ввода вывода необходима перегружать через дружественные функции?

Рейтинг: 0Ответов: 2Опубликовано: 29.06.2023

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

Ответы

▲ 3

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

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

▲ 2

Как мы все знаем, при перегрузке оператора у нас передаются аргументы:

  • Унарный оператор передает 1
  • Бинарный 2

При этом первый из них в неявном виде, через указатель на объект, который и вызвал эту функцию (this).

T obj1, obj2;
obj1 + obj2 -> obj1.operator+(obj2) // вызов функции из obj1
obj2 + obj1 -> obj2.operator+(obj1) // вызов функции из obj2

Из примера видно, что тут не совсем правила математики и перемена мест слагаемых играет роль. Если объекты одного типа, то все хорошо, но если разных, то возникают проблемы. Например пусть мы перегрузили оператор + с int для obj1:

obj1 + 10 // вызываем obj1.operator+(10) 
10 + obj1 // ??????? что вызывать ???????

И вот тут возникают проблемы. А если мы все таки хотим реализовать 10 + obj1 нам на помощь приходят дружественные функции, при их реализации нам нужно явно указать 2 передаваемых аргумента и мы можем , так же указать место :

friend T operator+(int a, T obj){
   obj.x += a;
   return obj;
}

Из (int a, T obj) видно, что мы первым передаем int аргумент и потом уже наш объект. Вообще дружественные функции редко используются, часто можно видеть их если нужно перегрузить операторы >> и << для потока ввода и вывода, а так на свое усмотрение.

Еще один момент, чтобы вы не запутались, перегрузка оператора будет работать, даже если вы не укажете в классе ее ка дружественную(главное чтобы компилятор видел функцию, но это скорее костыль и лучше так не делать), тогда у вас должны быть геттеры и сеттеры для доступа к приватным полям класса, но реализация через дружественные функции более корректна и правильная, да и читается легче, т.к. в .h файле сразу ее видно и не будет проблем с видимостью.

Вот еще статья почитать, для ,большего понимая.