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

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

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?

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

4 ответа

Решение

Вопрос 1> Правда ли, что OutSideClass может иметь доступ ТОЛЬКО к открытым членам InSideClass?

да

Вопрос 2> Правда ли, что InSideClass может получить доступ ко всем членам OutSideClass?

Нет, в C++03. Да, в C++11.


Стандартный текст очень ясно об этом:

Стандарт C++ (2003) говорит в $11,8/1 [class.access.nest],

Члены вложенного класса не имеют специального доступа ни к членам включающего класса, ни к классам или функциям, которые предоставили дружбу включающему классу; должны соблюдаться обычные правила доступа (пункт 11). Члены включающего класса не имеют специального доступа к членам вложенного класса; должны соблюдаться обычные правила доступа (пункт 11).

Однако в стандартной цитате есть один недостаток. В нем говорится, что вложенные классы не имеют доступа к закрытым членам включающего класса. Но в C++ 11 это было исправлено: в C++ 11 вложенные классы действительно имеют доступ к закрытым членам включающего класса (хотя включающий класс по-прежнему не имеет доступа к закрытым членам вложенных классов).

Смотрите этот отчет о дефектах:

Как указывает@Nawaz, вложенные классы в C++03 не имеют специальных прав доступа для членов включающего класса. Однако это ограничение легко обойти, объявив вложенный класс в качестве друга.

class OutSideClass
{
...

    class InSideClass
    {
        ...
    };
    friend class InSideClass;
};

Все, что вложенные классы делают в C++, помещает внутренний класс в пространство имен внешнего класса. Чтобы создать экземпляр InSideClass из функции-члена OutSideClass, я бы просто сделал

InSideClass *instance = new InSideClass();

Если InsideClass был общедоступным, и я хотел создать экземпляр InSideClass из функции, которая не является членом OutSideClass, я бы набрал:

OutSideClass::InSideClass *instance = new OutSideClass::InSideClass();

В отличие от других языков, таких как Java, InSideClass и OutSideClass полностью отделены друг от друга.

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

Другие вопросы по тегам