Доступность классов вложенных классов С++
Учитывая следующий код без учета дружбы между двумя классами:
class OutSideClass
{
...
public:
int i_pub;
protected:
int i_pro;
private:
int i_pri;
class InSideClass
{
...
public:
int j_pub;
protected:
int j_pro;
private:
int j_pri;
};
};
Вопрос 1 > Правда ли, что OutSideClass может ТОЛЬКО доступ к открытым членам InSideClass
Вопрос 2 > Правда ли, что InSideClass может получить доступ ко всем членам OutSideClass
Пожалуйста, поправьте меня, если мое понимание неверно.
Ответы
Ответ 1
Вопрос 1 > Правда ли, что OutSideClass может ТОЛЬКО доступ к открытым членам InSideClass
Да
Вопрос 2 > Правда ли, что InSideClass может получить доступ ко всем членам OutSideClass
Нет, в С++ 03. Да, в С++ 11.
В стандартном тексте очень четко сказано:
Стандарт С++ (2003) говорит в $11.8/1 [class.access.nest],
Члены вложенного класса не имеют специального доступа к членам охватывающий класс, а также классы или функции, которые предоставили дружбе с окружающим классом; обычные правила доступа (пункт 11) должны соблюдаться. Члены закрывающего класса не имеют специальных доступ к членам вложенного класса; обычные правила доступа (статья 11) должны соблюдаться.
Однако стандартная цитата имеет один недостаток. Он говорит, что вложенные классы не имеют доступа к закрытым членам охватывающего класса. Но в С++ 11 он был исправлен: в С++ 11 вложенные классы имеют доступ к закрытым членам охватывающего класса (хотя вложенный класс по-прежнему не имеет доступа к закрытым членам вложенных классов).
См. этот отчет об ошибках:
Ответ 2
Как указывает @Nawaz , в С++ 03 вложенные классы не имеют специальных прав доступа к членам охватывающего класса. Однако это ограничение легко обойти, объявив вложенный класс как друга.
class OutSideClass
{
...
class InSideClass
{
...
};
friend class InSideClass;
};
Ответ 3
Все вложенные классы в С++ помещают внутренний класс в пространство имен внешнего класса. Чтобы создать экземпляр InSideClass из функции-члена OutSideClass, я просто сделал
InSideClass *instance = new InSideClass();
Если InsideClass был общедоступным, и я хотел создать экземпляр InSideClass из функции, которая не является членом OutSideClass, я бы набрал:
OutSideClass::InSideClass *instance = new OutSideClass::InSideClass();
InSideClass и OutSideClass в остальном полностью разделены, в отличие от других языков, таких как Java.
Ответ 4
Нет никаких специальных привилегий доступа для вложенного класса к окружающему классу.