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

Доступность классов вложенных классов С++

Учитывая следующий код без учета дружбы между двумя классами:

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

Пожалуйста, поправьте меня, если мое понимание неверно.

4b9b3361

Ответ 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

Нет никаких специальных привилегий доступа для вложенного класса к окружающему классу.