Why are friend functions "available" for derived classes only when using public inheritance?
Asked Answered
P

1

5

When a derived class inherits from a base class via public access, the question is the same as that in Are friend functions inherited? and why would a base class FRIEND function work on a derived class object? . However, if it inherits via protected or private access, there will be a visibility error.

When it inherits via public access, the accessibility of private members of A is the same as if inheriting via private access. What's the difference between them?

class A {
private:
    int a;
    friend void f();
};

class B : private A {
};

void f() {
    B obj;
    int x = obj.a;
}

int main() {
    f();
    return 0;
}
Prow answered 31/12, 2019 at 13:17 Comment(3)
As specified by the link, there is no friendship inheritance in C++, so f is not a friend of B, so f cannot access private base classes or members of B, so f cannot access B::a since it would need access to the private base class.Alexine
Does this answer your question? Are friend functions inherited? and why would a base class FRIEND function work on a derived class object?Uboat
Obviously, if you derive privately from a class, external code will essentially not see that you derives from that class. Thus given that external code does not see that B derive from A, then why would you expect f to be able to see that. When you do not derive publicly from a class, there no IS-A relationship between those classes. By the way, whenever possible, it is preferable to replace private or protected inheritance by containment. You want to avoid tight coupling as much as possible.Argumentative
T
7

As already pointed out in the answer linked above, friendship is not inherited. Thus, a friend of A is not also a friend of B. Having B inherit from A via private access means that all members of A are accessible as private members of B [class.access.base]/1. Since f is not a friend of B, it cannot access private members of B [class.access]/1.1. Since f is not a friend of B, the base class A of B is also not accessible from f [class.access.base]/4. Since the base class A of B is not accessible from f, there's also no way you could get to the A subobject of a B (of which you could access the members) in f [class.access.base]/5

Thurstan answered 31/12, 2019 at 13:52 Comment(2)
I'm confused that when inherits via public access, accessibility of private members of A is the same as inherits as private access, what's the differene between them?Prow
If A is a public base class of B, then a B & can be implicitly converted to an A &, so A::a is accessable, as foo is a friend of ADevi

© 2022 - 2024 — McMap. All rights reserved.