Если у меня три класса, A, B, C. A и B - друзья (двунаправленно). Кроме того, B и C друзья (двунаправленно). У A есть указатель на B, а у B есть указатель на C. Почему A не может получить доступ к личным данным C через указатель?
Просто для пояснения: это чисто теоретический вопрос языка C++, а не вопрос совета по дизайну.
Дружественные классы чаще всего можно устранить, немного изменив дизайн. Это как бы вредит принципам объектно-ориентированного проектирования и увеличивает взаимосвязь с ИМО.





Дружба в C++ не транзитивна:
(A is friend of B) and (B is friend of C) does not mean (A is friend of C)
Кроме того, дружба не симметрична.
(A is friend of B) does not mean (B is friend of A)
Вы должны явно указать, что A является другом C, чтобы иметь возможность получить доступ к частным данным C изнутри A. Если добавление установщика и получателя к классу раскрывает информацию, не предназначенную для раскрытия, вам следует подумать о друзьях, если вы не можете обнаружите, что ваш дизайн неисправен (использование друга допустимо. Это не признак плохого дизайна). Если вы можете добавить сеттер и получатель, не разрушая интерфейс, вам следует избегать дружбы с другими классами. Обратите внимание, что вложенный класс всегда является другом вложенного класса. Таким образом, вложенный класс может видеть частные лица вложенного класса.
Я только что нашел эту статью, пока ждал ответов. Он довольно хорошо отвечает на мой вопрос: Область друзей в C++
Кратко опишите те части статьи, которые, по вашему мнению, решают вашу проблему.
Потому что в C++ дружба не является переходным свойством. На самом деле этого следует избегать, когда это возможно, потому что это усложняет систему.
Представьте, что B - это класс-посредник, а A и C - это компоненты, которыми нужно управлять. Неужели вы думаете, что имеет смысл, что кнопка должна иметь доступ к реализации флажка?
Между прочим, я не понимаю, где находится «иерархия» вашего заголовка в том случае, если вы спрашиваете.
Джон - мой друг, и он может использовать мое беспроводное соединение в любое время (я ему доверяю). Друг Джона Тим, тем не менее, расточитель, и хотя Джон - мой друг, я не считаю Тима своим другом, и поэтому я не позволяю ему использовать мое беспроводное соединение.
Кроме того, дети Джона - кучка хулиганов, поэтому я им не доверяю, либо они определенно не мои друзья, либо мои собственные дети, которым я доверяю, насколько я могу их бросить.
Хотя наши дети не могут напрямую получить доступ к беспроводной сети, они могут получить к ней доступ, если будут проходить через нас. Таким образом, дети Джона могут получить доступ к моей беспроводной сети, если они получают доступ к ней через Джона (т.е. они находятся под наблюдением и защищенный Джоном).
У Джона правительственная работа, поэтому ему, к сожалению, нельзя доверять никому, особенно когда дело касается беспроводной связи.
Это позволяет использовать такие вещи, как конструкторы копирования, где вы можете получить доступ к закрытому члену другого объекта, даже если нет реального доступа.
Так что я автоматически дружу со всеми моими клонами :-), поскольку они всего лишь другие экземпляры меня.
Ха! Я ни за что не забуду эту концепцию после прочтения вашего ответа :)
любой пример для последнего? [я новичок] помогите разобраться [конструктор копирования]
@Dineshkumar: Взгляните на любой конструктор копирования. К копируемому объекту напрямую обращается объект, созданный копией (даже если эти члены являются частными).
Все это хорошо подытожено здесь:
What does it mean that "friendship isn't inherited, transitive, or reciprocal"?
->
It means that classes derived from a friend class don't automatically become friends (do you trust the kids of your friends?), a friend of a friend doesn't automatically become a friend (do you trust the friends of your friends?), and that a class declaring another class as "friend" doesn't automatically become a friend of that class (do you trust anyone who calls you a friend?).
из
Что интересно, это легко обойти, добавив функции «getter» для получения указателей. (Получатель B вызова A, который вызывает получатель C.)