81

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++仕様に関連するセクションを見つけることができません、そして誰かがそれが合法であるか合法でないかを言うであろう特定の何かを引用することができればそれは素晴らしいでしょう。

4

5 に答える 5

81

ここで多かれ少なかれ同じ質問をした後、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
        }
    };
}
于 2013-02-07T19:41:22.750 に答える
49

C ++ 11まで(つまり、C++98およびC++03)

C++98およびC++03では、ネストされたクラスはデフォルトでアクセスできずprivate、それを囲むクラスのメンバーにアクセスできません。protected

C ++標準(2003)は、$ 11.8 /1[class.access.nest]で次のように述べています。

ネストされたクラスのメンバーは、囲んでいるクラスのメンバーや、囲んでいるクラスに友情を与えているクラスや関数に特別にアクセスすることはできません。通常のアクセス規則(第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以降削除されました。これで、ネストされたクラスは、囲んでいるクラスのとメンバーにアクセスできます。privateprotected

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
   }
};

お役に立てば幸いです。

于 2011-02-16T07:40:21.620 に答える
16

質問者は答えの1つを受け入れたようですので、これは単なる補足です。
この規格は、アクセシビリティに関する仕様を変更したようです。

C++98の§11.8/1は次のように述べています。

ネストされたクラスのメンバーは、囲んでいるクラスのメンバーにも、囲んでいるクラスに友情を与えているクラスや関数にも特別なアクセス権を持っていません。通常のアクセス規則に従うものとします。

N1804(TR1の後)の§11.8/ 1は次のように述べています:

ネストされたクラスはメンバーであるため、他のメンバーと同じアクセス権があります。

現在のC++コンパイラは新しい仕様に従っていると思います。

于 2011-02-16T09:23:05.527 に答える
4

この回答は、(古い)C++03仕様に関連しています。この質問で受け入れられた回答は、より最新のものです。

さて、これをカバーする仕様の関連部分を見つけたので、今この質問をするのはばかげています:§11.8/ 1:

ネストされたクラスのメンバーは、囲んでいるクラスのメンバーにも、囲んでいるクラスに友情を与えているクラスや関数にも特別なアクセス権を持っていません。通常のアクセス規則(第11条)に従うものとします。囲んでいるクラスのメンバーは、ネストされたクラスのメンバーに特別にアクセスすることはできません。通常のアクセス規則(第11条)に従うものとします。

(私の強調)

したがって、いいえのように見えます。内部クラスには特別なアクセス権限がありません。

于 2011-02-16T07:46:29.217 に答える
3

頭のてっぺんから正確な位置はわかりませんが、仕様を読んで、クラス内のプライベートデータがネストされたクラスを含む他のすべてのクラスから隠されていることに気付いたことを思い出します。

基本的に、クラスをネストすると、アクセス権限ではなく、特定のスコープが定義されます。

于 2011-02-16T07:40:35.300 に答える