Доступ к закрытым данным члена внешнего класса во внутреннем классе - PullRequest
7 голосов
/ 15 января 2012

Имеется этот код:

#include <iostream>

class Outer{
    int a; // private data member of class Outer
public:
    Outer(): a(55){}
    class Inner{
    public:
        void fun(Outer ob){
            std::cout << ob.a << std::endl;
        }
    };
};

int main() {

    Outer::Inner object;
    object.fun(Outer()); // prints 55
    //std::cout << (Outer().a) << std::endl; error: 'int Outer::a' is private

    return 0;
} 

Почему Внутренний класс имеет доступ к закрытым данным члена 'a' класса Outer?После этой статьи XL C / C ++ V8.0 для Linux он не должен компилироваться, однако он компилируется на g ++ 4.4.0.

Ответы [ 2 ]

9 голосов
/ 15 января 2012

C ++ 03 Standard $ 11,8 / 1: [class.access.nest]

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

Но это недостаток:

45.Доступ к вложенным классам

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

C ++ 11 Стандарт 11.7 Вложенные классы: говорит

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

class E {
  int x;
  class B { };
  class I {
    B b; // OK:E::I can accessE::B
    int y;
    void f(E* p, int i) {
      p->x = i; // OK:E::I can accessE::x
    }
  };
  int g(I* p) {
    return p->y; // error:I::y is private
  }
};
—end example]

Пример похож на тот, о котором вы говорите, и наглядно показывает его правильное поведение.

4 голосов
/ 15 января 2012

Согласно этому документу XL C / C ++ V8.0 не поддерживает C ++ 11, см. Раздел «Соответствие стандартам языка».

Компилятор поддерживает следующие спецификации языка программирования для C и C ++:

  • ИСО / МЭК 9899: 1999 (С99)
  • ИСО / МЭК 9899: 1990 (именуемый С89)
  • ИСО / МЭК 14882: 2003 (называемый стандартом С ++)
  • ISO / IEC 14882: 1998, первая официальная спецификация языка (именуемый C ++ 98)

Текущий стандарт гласит (ISO / IEC 14882: 2011 11.7):

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

В предыдущем языковом стандарте, был ли этот доступ или не разрешен, или, по крайней мере, было неясно, должен ли он быть разрешен в зависимости от вашей интерпретации.

...