2013-07-17 9 views
5

のプライベートメンバーにアクセスすることができ、私はthis articleを読んでいる、と私は(問題なくコンパイル:http://ideone.com/hRiV5B):このスニペットの中に私を驚かせた何かに気づいたとき、しばらくの間、memberspaceイディオムで遊んでたMemberspacesは、親クラス

class HugeClass 
{ 
    public: 
     struct memberspace 
     { 
      int f() const { return parent.f; } 

      private: 
       friend HugeClass; 
       explicit memberspace(HugeClass & parent) 
       : parent(parent) {} 
       HugeClass & parent; 
     } memberspace; 

     HugeClass() : memberspace(*this), f(42) {} 

    private: 
     int f; 
}; 

HugeClass::fのアクセスは許可されていないと私は考えていました。fはそのコンテキストではプライベートなので、コンパイルエラーです。

HugeClassmemberspacefriendなので、HugeClassmemberspaceのプライベートコンストラクタを呼び出すことができますが、なぜそれが明示的にHugeClassmemberspacefriendを宣言しなくても、他の方法で回避しますか?

+0

メンバー空間はHugeClassの一部とみなされ、したがってフルアクセス権を持ちます。いくつかの人気のコンパイラは、多くのための新しいルールを、次のしてきたが、2011年以前の基準は、(「入れ子になったクラスのメンバーは、囲むクラスのメンバーへの特別なアクセス権を持っていない」)反対を言ったので、これが唯一の正式ケースであることを –

答えて

6

C++での言語規則による。

ネストされたクラスはメンバーであり、他のメンバーと同じアクセス権を持ちます。 例:

class E { 
    int x; 
    class B { }; 
    class I { 
    B b; // OK: E::I can access E::B 
    void f(E* p, int i) 
    { 
     p->x = i; // OK: E::I can access E::x 
    } 
    }; 
}; 

そして、C++ 03で入れ子になったクラスの

メンバーが囲むクラスのメンバーに、またクラスに特別なアクセス権を持っていませんでした。囲むクラスに友情を与えた関数、または 通常のアクセス規則(第11条)は に従います。

したがって、C++ 11の例は、C++ 03コンパイラでは使用できません。

+4

注意年。 –

+0

@MikeSeymourありがとうございます。それは答えを投稿する前にもC++ 03の標準を読む理由です – ForEveR

+1

それは非常に興味深いです。これに関する詳しい情報を探しているうちに、私は言語の欠陥レポートを見つけました:http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45その文書から、実際には私はそれが有効だと思います元の動作が言語の欠陥とみなされたため、C++ 03(C++ 11だけでなく)で – nijansen

1

memberspaceHugeClassの一部であり、クラスの他のメンバーのように同じアクセス権を持っています。