web-dev-qa-db-ja.com

内部クラスはプライベート変数にアクセスできますか?

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」という名前のメンバーがない場合、これはエラーになります

104
kal

内部クラスは、内部クラスが定義されているクラスのフレンドです。
あ、はい;タイプ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();
}
108
Martin York

内部クラスは外部クラスのすべてのメンバーにアクセスできますが、親クラスインスタンスへの暗黙的な参照はありません(Javaの奇妙な点とは異なります)。したがって、外部クラスへの参照を内部クラスに渡すと、外部クラスインスタンスのすべてを参照できます。

25
MSN

なんでも  of Outerは、Outerのすべてのメンバー(パブリックまたはプライベート)にアクセスできる必要があります。

編集:コンパイラは正しい、varはInnerのメンバーではありません。ただし、Outerのインスタンスへの参照またはポインターがある場合は、それにアクセスできます。

6
Mark Ransom

varは内部クラスのメンバーではありません。

Varにアクセスするには、外部クラスインスタンスへのポインターまたは参照を使用する必要があります。例えばpOuter-> varは、内部クラスが外部のフレンドである場合、またはC++標準に厳密に従っている場合、varがパブリックである場合に機能します。

一部のコンパイラは、内部クラスを外部のフレンドとして扱いますが、そうでないものもあります。 IBMコンパイラのこのドキュメント を参照してください:

「ネストされたクラスは、別のクラスのスコープ内で宣言されます。ネストされたクラスの名前は、それを囲むクラスに対してローカルです。明示的なポインター、参照、またはオブジェクト名を使用しない限り、ネストされたクラスの宣言は、型名、静的メンバー、および包含クラスとグローバル変数からの列挙子。

ネストされたクラスのメンバー関数は、通常のアクセスルールに従い、それらを囲むクラスのメンバーに対する特別なアクセス特権を持ちません。外側のクラスのメンバー関数には、ネストされたクラスのメンバーへの特別なアクセス権はありません。」

1
xiaochuanQ