2012-04-05 10 views
7

私は次のクエリを持っています。継承と友情のアクセス。 C++

classB inherits from classA 
classC is friend of classB 

これは、classCがclassAの保護されたメンバーにアクセスできるはずではないということですか? classBはclassAからこれを継承するので、classCはclassBクラスのすべてにアクセスできますか?

答えて

6

それはclassCclassBの保護classAサブオブジェクトの一部にアクセスすることができなければならないことを意味します。 でないと、から非公開のものにアクセスすることはできません。例えば

class C; 

class A 
{ 
protected: 
    int i; 
}; 

class B: 
    public A 
{ 
    friend class C; 
}; 

class C 
{ 
public: 
    void foo(A& a, B& b) 
    { 
    // a.i = 3; // not allowed 
    b.i = 3; // allowed, accesses the `i` of the `A` subobject of `B` 
    } 
}; 
+0

これは最初の質問に対するより良い回答です。 –

+0

@KerrekSB:ありがとうございます。 – celtschk

8

[私の元の答えはナンセンスでした。それについての謝罪。それを指摘し、より良い答えを提供するための@celtschkをお願いいたします。] CBの友人がある

場合、それは、プライベート、パブリック、または保護されたかどうか、Bのメンバーのすべてにアクセスすることができ、それは、ベースサブオブジェクトの一部であるアクセス可能(publicおよびprotected)メンバー:

struct A { protected: int a; }; 
struct B : A { private: int b; friend struct C; } 

struct C 
{ 
    B x; 
    A w; 

    void f() 
    { 
     x.a = 1; // fine 
     x.b = 2; // fine 

     // w.a = 0; /* Error, #1 */ 
    } 

    friend struct D; // see below 
}; 

しかし、友情は推移も継承もない:CBの友人ですが、Aの(#1を参照)ではありません。また、D場合Cの友人は、その後、D「はBへの友情をもたらすのでDBアクセスすることができません」Cは、アクセスのいずれかを取得していないの非パブリックメンバーを。 Cからstruct E : C継承する場合も同様に、その後、Eも自動的Bの友人ではありません。

struct D 
{ 
    B y; 
    void g() 
    { 
     // y.b = 3; /* Error! */ 
    } 
}; 

struct E : C 
{ 
    B z; 
    void h() 
    { 
     // y.b = 4; /* Error! */ 
    } 
} 

おそらく1は、いくつかのポイントで何が起こっているかを要約することができます

  • 派生クラスは、アクセス権を持っています各基本クラスのすべての公開メンバーと保護されたメンバーに送信します。

  • クラスのフレンドは、そのクラスにアクセスできるすべてのメンバー(つまり、プライベートベースメンバーを除くすべてのメンバー)にアクセスできます。

  • 友人関係が継承されない:クラスにフレンドがある場合、そのフレンドシップは基本クラスも派生クラスのいずれにも適用されません。

  • 友人の友人は友人ではありません。

+0

またB'の 'A'サブオブジェクト'の保護されたメンバーにアクセスすることができます。任意の 'A'オブジェクトの保護されたメンバーにアクセスすることはできません(ただし、' B'もできません)。 – celtschk

+0

@celtschk:私の答えは完全に間違っていると思います。私はそれを改訂する必要があります。 –

+0

これはまだ完全ではありません。もちろん、 'B'自身がアクセスできる' A'サブオブジェクトのメンバーにのみアクセスできます。書かれているように、それはまた、 'A'のプライベートメンバーにアクセスする必要があります。 – celtschk