Введение
Класс "друг" в C++ может получить доступ к частным и защищенным членам класса, в котором он объявлен другом. Значительное использование класса "друг" для части структуры данных, представленной классом, обеспечивает доступ к основному классу, представляющему эту структуру данных. Механизм класса друзей позволяет расширить хранилище и доступ к частям, сохраняя при этом правильную инкапсуляцию, как это видят пользователи структуры данных. Подобно классу "друг", функция "друг" - это функция, которая предоставляет доступ к частным и защищенным членам класса, в котором она объявлена другом.
Инкапсулирование
Правильное использование классов друзей увеличивает инкапсуляцию, потому что позволяет расширить частный доступ структуры данных к ее частям, которыми владеет структура данных, не допуская частного доступа к любому другому внешнему классу. Таким образом, структура данных остается защищенной от случайных попыток нарушить инварианты структуры данных извне. Важно отметить, что класс не может предоставить себе доступ к частной части другого класса; это нарушило бы инкапсуляцию. Скорее, класс предоставляет доступ к своим частным частям другому классу, объявляя этот класс другом. В примере графа Graph не может объявить себя другом Vertex. Вертикаль объявляет Graph другом, и таким образом предоставляет Graph доступ к своим частным полям. Тот факт, что класс сам выбирает себе друзей, означает, что дружба не симметрична в целом. В примере графа Vertex не может получить доступ к частным полям Graph, хотя Graph может получить доступ к частным полям Vertex.
Альтернативы
Аналогичная, но не эквивалентная, языковая функция предоставляется ключевым словом внутреннего модификатора доступа C #, который позволяет классам внутри одного и того же сборника получать доступ к частным частям других классов. Это соответствует тому, чтобы отметить каждый класс другом другого в том же собрании; классы друзей более мелкие. Языки программирования, которые не поддерживают классы друзей или аналогичные языковые функции, должны будут внедрять обходные пути для достижения безопасного интерфейса на основе частей к структуре данных. Примеры таких обходных решений: Публичность полей деталей. Это решение уменьшает инкапсуляцию, позволяя нарушать инварианты структуры данных извне. Переместить все изменяемые структурные данные из части в структуру данных и ввести непрямую обратную связь от каждой части к ее структуре данных. Это решение изменяет организацию структуры данных и увеличивает потребление памяти в случаях, когда в противном случае эта информация не была бы необходима.
Make the parts' fields public. This solution decreases encapsulation by making it possible to violate invariants of the data structure from outside. Move all mutable structural data away from the part to the data structure, and introduce indirection back from each part to its data structure. This solution changes the organization of the data structure, and increases memory consumption in cases where there would otherwise be no need for this information.
Свойства
Дружба не симметрична если класс А является другом класса В, класс В не является автоматически другом класса А. Дружба не является транзитивной если класс А является другом класса B, а класс B является другом класса C, класс A не является автоматически другом класса C. Дружба не наследуется если класс База является другом класса X, подкласс Derived не является автоматически другом класса X; и если класс X является другом класса База, класс X не является автоматически другом подкласса Derived. Однако, если класс Y является другом подкласса Derived, класс Y также будет иметь доступ к защищенным частям класса Base, так же, как и подкласс Derived.
Friendships are not inherited – if class Base is a friend of class X, subclass Derived is not automatically a friend of class X; and if class X is a friend of class Base, class X is not automatically a friend of subclass Derived. However, if class Y is a friend of subclass Derived, class Y will also have access to protected portions of class Base, just as subclass Derived does.