Могут ли внутренние классы получить доступ к закрытым переменным?

class Outer {

    class Inner {
    public:
        Inner() {}
        void func() ;
    };

private:
    static const char* const MYCONST;
    int var;
};

void Outer::Inner::func() {
    var = 1;
}

const char* const Outer::MYCONST = "myconst";

Эти ошибки при компиляции с классом Outer:: Inner 'не имеют имени с именем `var'

Ответ 1

Внутренний класс является другом класса, который он определен внутри.
Так да; объект типа Outer::Inner может получить доступ к переменной-члену var объекта типа Outer.

В отличие от Java, однако, нет никакой связи между объектом типа Outer::Inner и объектом родительского класса. Вы должны установить родительские дочерние отношения вручную.

#include <string>
#include <iostream>

class Outer
{
    class Inner
    {
        public:
            Inner(Outer& x): parent(x) {}
            void func()
            {
                std::string a = "myconst1";
                std::cout << parent.var << std::endl;

                if (a == MYCONST)
                {   std::cout << "string same" << std::endl;
                }
                else
                {   std::cout << "string not same" << std::endl;
                }
            }
        private:
            Outer&  parent;
    };

    public:
        Outer()
            :i(*this)
            ,var(4)
        {}
        Outer(Outer& other)
            :i(other)
            ,var(22)
        {}
        void func()
        {
            i.func();
        }
    private:
        static const char* const MYCONST;
        Inner i;
        int var;
};

const char* const Outer::MYCONST = "myconst";

int main()
{

    Outer           o1;
    Outer           o2(o1);
    o1.func();
    o2.func();
}

Ответ 2

Внутренний класс имеет доступ ко всем членам внешнего класса, но не имеет неявной ссылки на экземпляр родительского класса (в отличие от некоторой странности с Java). Поэтому, если вы передаете ссылку на внешний класс во внутренний класс, он может ссылаться на что-либо в экземпляре внешнего класса.

Ответ 3

Все, что есть part Outer, должно иметь доступ ко всем членам Outer, открытым или закрытым.

Изменить: ваш компилятор верен, var не является членом Inner. Но если у вас есть ссылка или указатель на экземпляр Outer, он может получить к ней доступ.

Ответ 4

var не является членом внутреннего класса.

Для доступа к var следует использовать указатель или ссылку на экземпляр внешнего класса. например pOuter- > var будет работать, если внутренний класс является другом внешнего, или var является общедоступным, если строго следовать стандарту С++.

Некоторые компиляторы рассматривают внутренние классы как друг внешнего, но некоторые не могут. См. этот документ для компилятора IBM:

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

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

Ответ 5

Прежде всего, вы пытаетесь получить доступ к нестатическому члену var вне класса, что запрещено в C++.

Отметьте, что ответ правильный.

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

Таким образом, вы можете сделать две вещи: либо объявить var как static, либо использовать ссылку на экземпляр внешнего класса для доступа к 'var' (потому что класс или функция друга также нуждается в ссылке для доступа личные данные).

Статическая переменная

Измените var на static, если вы не хотите, чтобы var был связан с экземплярами класса.

#include <iostream>

class Outer {

private:
    static const char* const MYCONST;
    static int var;

public:
   class Inner {
    public:
        Inner() {
          Outer::var = 1;
        }
        void func() ;
    };
};

int Outer::var = 0;

void Outer::Inner::func() {
    std::cout << "var: "<< Outer::var;
}

int main() {
  Outer outer;
  Outer::Inner inner;
  inner.func();

}

Output- var: 1

Нестатическая переменная

Ссылка на объект должна иметь доступ к любым нестатическим переменным-членам.

#include <iostream>

class Outer {

private:
    static const char* const MYCONST;
    int var;

public:
   class Inner {
    public:
        Inner(Outer &outer) {
          outer.var = 1;
        }
        void func(const Outer &outer) ;
    };
};

void Outer::Inner::func(const Outer &outer) {
    std::cout << "var: "<< outer.var;
}

int main() {
  Outer outer;
  Outer::Inner inner(outer);
  inner.func(outer);

}

Output- var: 1

Изменить - Внешние ссылки - это ссылки на мой блог.