Внутренние классы в C++ автоматически друзей?
Если я определяю внутренний класс В C++, это автоматически друг из класса, который его содержит? Например, это законно:
class Outer {
public:
class Inner {
public:
void mutateOuter(Outer& o);
};
private:
int value;
};
void Outer::Inner::mutateOuter(Outer& o) {
o.value ++; // Legal? Or not?
}
Я спрашиваю, потому что на некоторых компиляторах я пробовал (VS2003) этот код не будет работать, но я слышал, по крайней мере, анекдотично, что он работает на некоторых компиляторах. Я не могу найти соответствующий раздел в спецификации C++ об этом, и если кто-то может привести что-то конкретное, что скажет, что это или не законно, это было бы здорово.
5 ответов:
задав более или менее тот же вопрос здесь Я сам хотел поделиться (по-видимому) обновленным ответом на C++11:
цитируется из https://stackoverflow.com/a/14759027/1984137:
стандартные 11.7.1$
"вложенный класс является членом и имеет те же права доступа, как любой другой член. Члены объемлющего класса не имеют специального доступ к членам вложенного класса; обычная правила доступа должны быть повиновался"
и обычные правила доступа указывают, что:
" член класса может также получить доступ ко всем именам, к которым относится класс иметь доступ..."
конкретные примеры были приведены в стандарте:
class E { int x; class B { }; class I { B b; // OK: E::I can access E::B int y; void f(E* p, int i) { p->x = i; // OK: E::I can access E::x } }; }
до C++11 (т. е. C++98 и C++03)
в C++98 и C++03, вложенный класс не может открыть
privateиprotectedчлены включающего класса по умолчанию.стандарт C++ (2003) говорит в $11.8/1 [класс.доступ.гнездо],
члены вложенного класса не имеют специального доступа к членам заключительный класс, ни в классы, ни функции, которые предоставили дружбу к заключительному классу; обычный правила доступа (пункт 11) должны быть повиновался. члены вшита класс не имеет специального доступа к члены вложенного класса; обычный правила доступа (пункт 11) должны быть повиновался.
пример из самого стандартного:
class E { int x; class B { }; class I { B b; // error: E::B is private int y; void f(E* p, int i) { p->x = i; // error: E::x is private } }; int g(I* p) { return p->y; // error: I::y is private } };С C++11
вышеуказанное ограничение было удалено с C++11. Теперь вложенные классы можете доступ в интернет
privateиprotectedчлены вшита класс:class E { int x; class B { }; class I { B b; // ok: even though E::B is private int y; void f(E* p, int i) { p->x = i; // ok: even though E::x is private } }; int g(I* p) { return p->y; // ok: even though I::y is private } };надеюсь, что это поможет.
поскольку вопрос, похоже, принял один из ответов, это просто дополнение.
Стандарт, похоже, изменил спецификацию о доступности.§11.8/1 в C++98 гласит:
члены вложенного класса не имеют специального доступа к членам включающего класса или классов или функции, которые предоставили дружбу к заключительному классу; обычный правила доступа должны быть повиновался.
§11.8 / 1 в N1804 (после TR1) состояния:
вложенный класс является членом и как таковой имеет те же права доступа, что и любой другой другой участник.
Я думаю, что текущие компиляторы C++ подчиняются более новой спецификации.
этот ответ относится к (устаревшей) спецификации C++03. принятый ответ на этот вопрос более актуален.
Ну, я чувствую себя глупо, задавая этот вопрос сейчас, потому что я только что нашел соответствующую часть спецификации, которая охватывает это: §11.8/1:
члены вложенного класса не имеют специального доступа к членам объемлющего класса, ни в классы или функции, которые предоставили дружбы внешнего класса; обычная правила доступа (пункт 11) должны соблюдаться. члены заключающего класса не имеют специального доступа к членам вложенного класса; обычные правила доступа (пункт 11) должны соблюдаться
(Курсив мой)
таким образом, похоже, что нет, внутренние классы не имеют специальных прав доступа.
Я не знаю точного местоположения с верхней части моей головы, но я помню, что читал спецификации и обнаружил, что любые личные данные в классе скрыты от всех других классов, включая вложенные классы.
в принципе, вложенность класса определяет определенную область, а не привилегии доступа.
Comments