Вложенные классы: доступ к защищенному члену включающего класса из вложенного защищенного класса

Этот код компилируется в msvc / g ++:

class A{
protected:
    int i;
    class B{
    public:
        A* a;
        B(A* a_)
        :a(a_){
        }
        void doSomething(){
            if (a)
                a->i = 0;//<---- this part
        }       
    };
public:
    A()
    :i(0){
    }
};

Как видите, B получает доступ к «protected msgstr "раздел включающего класса, хотя он не объявлен как друг.

Это стандартное (соответствующее стандартам) поведение?

Я иногда использую эту функцию, но не помню правила, согласно которому вложенный защищенный класс должен автоматически получать доступ ко всем защищенным данным включающего класса.

18
задан SigTerm 21 August 2010 в 14:56
поделиться

4 ответа

В стандарте C ++ 03 в 11.8p1 сказано:

Члены вложенного класса не имеют специального доступа к членам включающего класса.

Однако разрешение для отчета о дефектах 45 (к стандарту) утверждает обратное и, следовательно, определяет поведение, которое вы видите:

Вложенный класс является членом и, как таковой, имеет тот же доступ права, как и любой другой член.

В C ++ 0x текст 11.8 был изменен, чтобы отразить этот факт,так что это допустимое поведение для компиляторов, соответствующих C ++ 03 и C ++ 0x.

См. Также эту ветку на форумах cprogramming.com .

15
ответ дан 30 November 2019 в 08:58
поделиться

У меня нет под рукой копии C ++ 03, но есть черновик (n3090) C ++ 0x:

11.8 Вложенные классы

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

[Пример:

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
        }
    };
    int g(I* p) {
        return p->y; // error: I::y is private
    }
};

Итак, по крайней мере, в следующем стандарте вложенные классы могут обращаться к членам внешнего класса, как и любая обычная функция-член.

Обновление: Это запрещено текущим стандартом. Но отчет о дефекте ( DR 45 ) был подан, чтобы исправить это. (Редакция SigTerm убрала это. Пожалуйста, будьте осторожны.)

Обновление №2: Я пробовал с VS2010, g ++ (4.0.1 Apple) с -Wall -ansi -pedantic -std = c ++ 98 и Comeau (4.3.10.1) в строгом режиме C ++ 03 с отключенными расширениями C ++ 0x - все они, похоже, принимают доступ к членам внешнего класса private в члены внутреннего класса.

5
ответ дан 30 November 2019 в 08:58
поделиться

См. 9,7 долл. США / 1.

«Вложенный класс находится в области действия своего включающего класса. За исключением использования явных указателей, ссылок и имен объектов, объявления во вложенном классе могут использовать только имена типов, статические члены и перечислители из включающего класса "

0
ответ дан 30 November 2019 в 08:58
поделиться

Является ли это стандартным (соответствующим стандарту) поведением?

Нет .

Согласно C ++ - 2003

Раздел 11.8.1

Вложенные классы

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

[Example:
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
    }
};
—end example]

Но есть небольшая модификация этого раздела в ISO / IEC N 3092 , в котором говорится

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

0
ответ дан 30 November 2019 в 08:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: