Inheritance and Friendship access. C++

Go To StackoverFlow.com

7

I have the following query;

classB inherits from classA 
classC is friend of classB

Doesn't this mean classC should be able to access protected member of classA? Since classB inherits this from classA, an classC can access everything in class classB?

2012-04-05 20:37
by user1005253


6

It means that classC should be able to access the protected classA subobject part of classB. It should not be able to access anything non-public from classA itself.

For example:

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`
  }
};
2012-04-05 20:47
by celtschk
This is the better answer for the original question - Kerrek SB 2012-04-05 21:08
@KerrekSB: Thank you - celtschk 2012-04-05 21:15


8

[My original answer was nonsense. Apologies for that. Thank you to @celtschk for pointing that out and providing the better answer.]

If C is a friend of B, it can access all of B's members, whether private, public, or protected, and that includes the accessible (public and protected) members that are part of a base subobject:

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

However, friendship is neither transitive nor inherited: C is a friend of B, but not of A (see #1). Also, if D is a friend of C, then D doesn't get any of the access that C's friendship to B affords it, so D cannot access B's non-public members. Similarly, if struct E : C inherits from C, then E is also not a friend of B automatically:

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

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

Perhaps one can summarize what's going on in a few points:

  • A derived class has access to all public and protected members of each base class.

  • A friend of a class has access to all members of that class that are accessible to it (i.e. all members excluding private base members).

  • Friendship is not inherited: If a class has a friend, that friendship does not apply to any of its base classes nor to any of its derived classes.

  • A friend of a friend is not a friend.

2012-04-05 20:40
by Kerrek SB
It can also access the protected members of B's A subobject. It just cannot access protected members of arbitrary A objects (but neither can B) - celtschk 2012-04-05 20:51
@celtschk: I think my answer is completely wrong. I need to revise it - Kerrek SB 2012-04-05 20:57
It's still not completely correct: It of course can access only those members of the A subobject which B itself can access. As written, it should also have access to A's private members - celtschk 2012-04-05 21:07
@celtschk: yes, I was just editing that - Kerrek SB 2012-04-05 21:09
Ads