次のクエリがあります。
classB inherits from classA
classC is friend of classB
これは、classCがclassAの保護されたメンバーにアクセスできる必要があるという意味ではありませんか?classBはこれをclassAから継承するので、classCはクラスclassBのすべてにアクセスできますか?
次のクエリがあります。
classB inherits from classA
classC is friend of classB
これは、classCがclassAの保護されたメンバーにアクセスできる必要があるという意味ではありませんか?classBはこれをclassAから継承するので、classCはクラスclassBのすべてにアクセスできますか?
[私の最初の答えはナンセンスでした。そのことをお詫びします。それを指摘し、より良い答えを提供してくれた@celtschkに感謝します。]
C
のフレンドである場合、プライベート、パブリック、または保護されているかどうかに関係B
なく、すべてののメンバーにアクセスできます。これには、ベースサブオブジェクトの一部であるアクセス可能な(パブリックおよび保護された)メンバーが含まれます。B
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
};
ただし、友情は推移的でも継承的でもありません。はのC
友人ですが、の友人ではありB
ませんA
(#1を参照)。また、D
がの友だちである場合、友情がそれを提供するためのC
アクセス権D
を取得しないため、非公開メンバーにアクセスすることはできません。同様に、から継承する場合、それも自動的にの友達ではありません:C
B
D
B
struct E : C
C
E
B
struct D
{
B y;
void g()
{
// y.b = 3; /* Error! */
}
};
struct E : C
{
B z;
void h()
{
// y.b = 4; /* Error! */
}
}
おそらく、何が起こっているのかをいくつかの点で要約することができます。
派生クラスは、各基本クラスのすべてのパブリックメンバーと保護されたメンバーにアクセスできます。
クラスの友達は、そのクラスにアクセスできるそのクラスのすべてのメンバー(つまり、プライベートベースメンバーを除くすべてのメンバー)にアクセスできます。
友情は継承されません:クラスに友人がいる場合、その友情はその基本クラスにも派生クラスにも適用されません。
友達の友達は友達ではありません。
これは、の保護されたサブオブジェクト部分classC
にアクセスできる必要があることを意味します。それ自体から非公開のものにアクセスできないようにする必要があります。classA
classB
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`
}
};