Функции и классы друзей не нарушают инкапсуляцию, когда вы пытаетесь создать абстракцию или интерфейс, который должен физически охватывать несколько классов или функций C ++! Вот почему друг был изобретен.
Эти типы случаев встречаются не часто, но иногда вы вынуждены реализовывать абстракцию или интерфейс с различными классами и функциями. Классическим примером является реализация некоторого типа класса комплексных чисел. Операторы, не являющиеся членами, получают дружбу с основным классом комплексных чисел.
Я также вспоминаю, как делал это при программировании на CORBA в C ++. CORBA заставил меня иметь отдельные классы для реализации слуг CORBA. Но для определенной части нашего программного обеспечения мне нужно было объединить их в один интерфейс. Дружба позволила этим двум классам работать вместе, чтобы обеспечить бесперебойную работу одной части нашего программного обеспечения.
Возможность пометить определенную функцию-член в другом классе как друга вашего класса может показаться даже странной, но это всего лишь способ жестко контролировать дружбу. Вместо того, чтобы разрешить весь другой класс "in" как ваш друг, вы разрешаете доступ только одной из его функций-членов. Опять же, это не часто, но очень полезно, когда вам это нужно.