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;
}
Boann
  • 48,794
  • 16
  • 117
  • 146
JM233333
  • 53
  • 5
  • 2
    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. – Holt Dec 31 '19 at 13:23
  • 2
    Does this answer your question? [Are friend functions inherited? and why would a base class FRIEND function work on a derived class object?](https://stackoverflow.com/questions/47469715/are-friend-functions-inherited-and-why-would-a-base-class-friend-function-work) – James Adkison Dec 31 '19 at 13:28
  • 2
    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. – Phil1970 Dec 31 '19 at 15:38

1 Answers1

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

Michael Kenzel
  • 15,508
  • 2
  • 30
  • 39
  • 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? – JM233333 Dec 31 '19 at 14:39
  • 1
    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 `A` – Chris Dodd Dec 31 '19 at 22:49