Почему функция-член PRIVATE не может быть функцией друга другого класса?

class x
{
void xx() {}
};

class y
{
friend void x::xx();
};

Это приводит к ошибке, как

ошибка: функция друга ‘xx’ является приватным членом ‘x’

Почему я не могу объявить приватную функцию-член другом другого класса?

19

Решение

[Class.friend] / 9:

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

Причина довольно проста; private Участники должны соблюдать четкое и определенное правило:

Членом класса может быть

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

Разрешение именования частных членов в объявлениях внутри несвязанных классов нарушило бы это правило: оно позволяет другому классу зависит от деталей реализации без явного разрешения. Это становится проблематичным, например, при изменении имени, типа или подписи частного участника или его полном удалении; это предназначено, чтобы не сломать интерфейс этого класса.

Это можно обойти, сделав весь x друг y:

class x {
void xx() {}
};

class y {
friend x;
};

демонстрация.

13

Другие решения

Идея создания x::xx private должно быть что x::xx это деталь реализации, на которую не должны полагаться другие классы. Это не просто означает, что x::xx не может быть вызван другими классами, это означает, или, скорее, это должно означать, что, например, переименование x::xx в x::xy не должен ломать ничего, кроме самого класса и его друзей.

В вашем случае переименование x::xx в x::xy вызовет класс y иметь ошибку, даже если это не друг x,

Чтобы избежать этого, нужно сделать y друг x, чтобы y может получить доступ x«s private члены. Затем он может объявить x::xx как friend,

(Примечание: более прямым ответом на вопрос «Почему компилятор не позволяет этого?» Является «Потому что стандарт не позволяет этого». Это естественным образом приводит к последующему вопросу «Почему стандарт этого не допускает?»). «Я пытаюсь ответить на этот вопрос.)

14

По вопросам рекламы [email protected]