В этом семестре в колледже у меня есть объектно-ориентированное программирование с курсом c ++, и мы изучали функции друзей.
Мне инстинктивно не нравится их способность обходить безопасность, которую обеспечивают Encapsulation и скрытие данных, я прочитал несколько статей в Интернете, и некоторые люди думали, что это было хорошей идеей с некоторыми законными применениями.
Что бы сказал эксперт ООП о функциях друзей в C ++? Должен ли я просто скользить по нему или я должен узнать больше об этом?
c++
object-oriented
friends
Нихилу
источник
источник
Ответы:
Не всегда удобно создавать все функции, относящиеся к членам класса C ++ этого класса. Например, представьте реализацию векторной алгебры со скалярным умножением. Мы хотим написать:
Мы можем сделать это с помощью функции-члена:
Но мы также хотели бы написать:
Это требует бесплатной функции:
friend
Ключевое слово было добавлено в C ++ , чтобы поддержать это использование. Функция free является частью реализации класса Vector и должна быть объявлена в том же заголовке и реализована в том же исходном файле.Точно так же мы можем использовать,
friend
чтобы упростить реализацию тесно связанных классов, таких как коллекция и итератор. Опять же, я бы объявил оба класса в одном заголовке и реализовал их в одном исходном файле.источник
inline Vector operator*(double a, Vector v) { return v*a; }
. Каноническое решение по сути.inline Vector operator*(double a, Vector v) { return -v*a; }
и это все еще не требует дружбы.Дружественные функции ничем не отличаются от функций-членов с точки зрения инкапсуляции. Однако они могут предложить и другие преимущества, такие как более общий характер, особенно в том, что касается шаблонов. Кроме того, некоторые операторы могут быть указаны только как свободные функции, поэтому, если вы хотите, чтобы у них был доступ к членам, вы должны
friend
.Лучше выполнять
friend
одну функцию, чем заставлять делать что-то, что вы не хотите публиковать. Это означает, что весь мир может использовать его - вместо одной функции.источник
friend
использовать функцию, которая также является «частной», например, объявленной только в одном TU.Если вы увлечены тем, что делаете, вы бы узнали все о C ++. Узнайте, для чего они используются, как их использовать, а затем - и только тогда - решите не использовать их. По крайней мере, вы будете готовы к чтению чужого кода, который использует этот аспект C ++.
источник
« Что бы сказал эксперт по ООП ... » Это в основном зависит от того, насколько он опытен в C ++, что - по своей собственной спецификации - не является (и не хочет быть) языком для пуриста.
ООП зилоты не используют С ++ (они предпочитают Smalltalk и любят Java).
Зелоты функционального программирования не используют C ++ (они предпочитают LISP и его наследников)
Большинству экспертов ООП не нравятся функции друзей просто потому, что они хотят, чтобы ООП-часть C ++ вела себя как Smalltalk. Но C ++ - это не Smalltalk, и они даже не могут понять, что друг не нарушает инкапсуляцию , по той простой причине, что функция не может быть другом вашего класса без вашего класса .
И с точки зрения «функциональности», между
a.fn(b)
иfn(a,b)
нет никакой разницы (гдеfn
друг): вовлеченные стороны одинаковы. Проще говоря, один синтаксис может быть более подходящим, чем другой: если fn является коммутативным относительноa
иb
,fn(a,b)
вероятно, более подходящим, чем тогдаa.fn(b)
(где взгляды имеют «особую роль», которой на самом деле это не так).источник
источник
C ++ FAQ является лаконичным:
FAQ представляет один из наиболее полезных способов мышления о дружбе:
Возможно, наиболее распространенное использование функций-друзей - это перегрузка << для ввода-вывода.
источник
Функции Friend лучше всего использовать для пользовательских определений операторов. Они полезны в других ситуациях, но если вы обнаружите, что часто задаете классы для друзей, то можете оказаться в обходе дизайна (просто хорошая самопроверка для использования при написании кода).
Будьте осторожны с утверждением «безопасность» в исходном вопросе. Модификаторы доступа предназначены для того, чтобы вы не могли написать плохой код случайно, как компилятор. Модификаторы доступа ограничивают интерфейс и служат для передачи информации о том, какие функции важны для использования класса (общедоступные и защищенные) и какие были созданы в рамках создания класса, более привлекательного для сопровождающих (приватного). Модификаторы не обеспечивают безопасность, так как существует множество способов получить доступ к частным данным. Например, получить указатель на класс и его размер и отправиться на рыбалку.
источник
Дружественные функции C ++ тесно связаны со следующей функциональностью:
Это означает, что они не имеют this-указатель и, следовательно, находятся за пределами класса / объекта. С другой стороны, они часто принимают параметры, которые делают их снова принадлежащими классу. Вот пример, поясняющий ссылку:
Единственное различие между статическими и дружественными функциями заключается в том, что дружественная функция может использовать несколько классов.
Использование дружественного механизма в c ++ требует программистов, которые имеют опыт программирования на c ++ около 10-15 лет, и поэтому изначально вам следует избегать этого. Это расширенная функция.
источник