Внутренние классы в 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++ об этом, и если кто-то может привести что-то конкретное, что скажет, что это или не законно, это было бы здорово.

601   5  

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

    Ничего не найдено.