Подтвердить что ты не робот

Область друзей в С++

Если у меня есть три класса, A, B, C. A и B являются друзьями (двунаправленно). Кроме того, B и C являются друзьями (двунаправленно). A имеет указатель на B и B имеет указатель на C. Почему не удается получить доступ к личным данным C через указатель?

Просто чтобы уточнить: это чисто теоретический вопрос на языке С++, а не вопрос дизайна.

4b9b3361

Ответ 1

Дружба в С++ не транзитивна:

Джон - мой друг, и он может использовать мое беспроводное соединение в любое время (я ему доверяю).
Джон друг Тим, хотя и является расточителем, и хотя Джон - мой друг, я не отношусь к Тиму как к другу, и поэтому я не позволяю ему использовать мое беспроводное соединение.

Дружба не наследуется

Кроме того, дети Джона - кучка хулиганов, поэтому я не доверяю им, или они определенно не мои друзья, и мои собственные дети, которым я доверяю, насколько я могу их бросить.

Хотя наши дети не могут напрямую обращаться к беспроводной сети, они могут получить к ней доступ, если они пройдут через нас. Таким образом, дети Джона могут получить доступ к моей беспроводной сети, если они обращаются к нему через Джона (т.е. Они контролируются и защищены от Джона).

Кроме того, дружба не симметрична.

У Джона есть правительственная работа, поэтому он, к сожалению, не может никому доверять, особенно когда речь идет о беспроводной связи.

Ты всегда лучший друг.

Это позволяет создавать такие объекты, как конструкторы копирования, где вы можете получить доступ к частному члену другого объекта, даже если нет реальных доступов.

Таким образом, я также автоматически поддерживаю все мои клоны:-), поскольку они являются только другими примерами самого себя.

Ответ 2

Дружба в С++ не транзитивна:

(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. Если добавление setter и getter в класс предоставляет информацию, которая не предназначена для раскрытия, вы должны подумать о друзьях, если вы не может найти ваш дизайн неисправным (использование друга действительно. Это не знак плохого дизайна). Если вы можете добавить сеттер и геттер, не разрушая интерфейс, вам следует избегать общения с другими классами. Обратите внимание, что вложенный класс всегда является другом класса вложенности. Таким образом, вложенный класс может видеть рядовых классов гнездования.

Ответ 3

Я только что нашел эту статью в ожидании ответов. Он очень хорошо отвечает на мой вопрос: Объём дружбы на С++

Ответ 4

Потому что в С++ дружба не является транзитивным свойством. На самом деле его следует избегать, когда это возможно, потому что оно вводит сложность в систему.

Представьте, что B является классом посредника, а A и C - это компоненты, которым необходимо управлять, действительно ли вы думаете, что имеет смысл, что кнопке должен быть необходим доступ к реализации флажка?

Кстати, я не вижу, где "иерархия" вашего названия находится в том случае, когда вы спрашиваете.

Ответ 5

Здесь все хорошо подытожено:

What does it mean that "friendship isn't inherited, transitive, or reciprocal"?

- >

Это означает, что классы, полученные из класса друзей, не автоматически становятся друзьями (вы доверяете детям своих друзей?), друг друга не автоматически становится другом (вы доверять друзьям своих друзей?), и что класс, объявляющий другой класс как "друг" автоматически не становится другом этот класс (вы доверяете любому, кто называет вас другом?).

от

http://yosefk.com/c++fqa/friend.html#fqa-14.4