继承和友谊访问.C++

use*_*253 7 c++ inheritance access-control friend

我有以下查询;

classB inherits from classA 
classC is friend of classB
Run Code Online (Sandbox Code Playgroud)

这是不是意味着classC应该能够访问classA的受保护成员?既然classB从classA继承了这个,那么classC可以访问类classB中的所有东西吗?

Ker*_* SB 8

[我原来的答案是胡说八道.为此道歉.感谢@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
};
Run Code Online (Sandbox Code Playgroud)

然而,友谊既不是传递性的,也不是遗传的: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! */
     }
}
Run Code Online (Sandbox Code Playgroud)

也许人们可以在几个方面总结一下发生了什么:

  • 派生类可以访问每个基类的所有公共成员和受保护成员.

  • 类的朋友可以访问该类可访问的所有成员(即除私有基础成员之外的所有成员).

  • 友谊不是继承的:如果一个类有一个朋友,那个友谊不适用于它的任何基类,也不适用于它的任何派生类.

  • 朋友的朋友不是朋友.


cel*_*chk 6

这意味着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`
  }
};
Run Code Online (Sandbox Code Playgroud)