Search code examples
c++inheritancepublicfriendprotected

Does 'friend' declaration affect the accessibility of members in the Base class?


I am confused on the effectiveness of a friend declaration.

In the first example, this friend declaration in Base caused me to not get an error on d.j and d.k in the main() function.

However, in the second example, it seems the friend declaration has no impact at all. The compiler throws errors in main() on d.i, d.j, d.k as well as d.m and d.n.

It seems public and protected inheritance only matters.

Example 1:

struct Base
{
    friend int main(); 

public:
    int i;

protected:
    int j;

private:
    int k;
};

struct Derived : public Base
{
public:
    int l;
protected:
    int m;
private:
    int n;
};

int main()
{
    Derived d; 
    d.i = 1;
    d.j = 2;
    d.k = 3;
    d.l = 4;
    d.m = 5; //error
    d.n = 6; //error

    return 0;
}

Example 2:

struct Base
{
    friend int main(); 

public:
    int i;

protected:
    int j;

private:
    int k;
};

struct Derived : protected Base
{
public:
    int l;
protected:
    int m;
private:
    int n;
};

int main()
{
    Derived d; 
    d.i = 1; //error
    d.j = 2; //error
    d.k = 3; //error
    d.l = 4;
    d.m = 5; //error
    d.n = 6; //error

    return 0;
}

Solution

  • d.i is a fiction. Derived does not have i in it. What it does have is a Base, which itself has an i in it. To get to d.i therefore, one must first be able to see Derived::Base.

    If you publicly inherit from a base class, that means any code can see the derived class's base class object. If you protectedly inherit from a base class, only code with protected access to the derived class can see the derived'd class's base class object.

    main is a friend of Base, not Derived. So it has no special access to Derived. Therefore, if you use protected inheritance, it cannot get to Derived::Base and therefore cannot see Derived::Base::i.