0

I have a bit confusion about inheritance and friendship. Consider this example:

    class D;
    class A
    {
    protected:
        int x = 0;
    private:
        int y = 1;
    public:
        int z = 2;
    friend class D;
    };
    
    class B :  public A
    {};
    
    class C : protected A
    {};
    
    class D
    {
    public:
        void f(B b){cout << b.x << b.y << b.z << endl;} // ok
        void f2(C c){cout << c.x << c.y << c.z << endl;} // error
    };
    
  • f(B b) is straightforward because b can access all the members of A because class D is a friend of class A.

  • But why f2(C c) doesn't compile? in fact C inherits protectedly from A and D is a friend of A so why f compiles and f2 doesn't? and how Derivation Access Specifier affect this? Thank you!

The output:

In member function ‘void D::f2(C)’: ../main.cpp:34:27: error: ‘int A::x’ is protected within this context 34 | void f2(C c){cout << c.x << c.y << c.z << endl;} // error | ^ ../main.cpp:16:8: note: declared protected here 16 | int x = 0; | ^ ../main.cpp:34:34: error: ‘int A::y’ is private within this context 34 | void f2(C c){cout << c.x << c.y << c.z << endl;} // error | ^ ../main.cpp:18:8: note: declared private here 18 | int y = 1; | ^ ../main.cpp:34:41: error: ‘int A::z’ is inaccessible within this context 34 | void f2(C c){cout << c.x << c.y << c.z << endl;} // error | ^ ../main.cpp:20:8: note: declared here 20 | int z = 2; | ^

Maestro
  • 2,512
  • 9
  • 24
  • Does the error messages give any hints? – Ted Lyngmo Jun 20 '20 at 23:59
  • @TedLyngmo: Yes I'll edit it. – Maestro Jun 20 '20 at 23:59
  • @TedLyngmo: Edited. – Maestro Jun 21 '20 at 00:01
  • The [error](https://godbolt.org/z/2ZXP_B) I think about is more that you pass by value and try to implicitly cast a `C` to an `A`. Have you tried references or pointers? – Ted Lyngmo Jun 21 '20 at 00:03
  • @TedLyngmo: The same thing with references and pointers. – Maestro Jun 21 '20 at 00:05
  • Ok, then make a [mcve]. Btw, why do you think `D` would have access to `A`'s private members? – Ted Lyngmo Jun 21 '20 at 00:06
  • @TedLyngmo: Because simply `D` is a friend of `A`. – Maestro Jun 21 '20 at 00:09
  • 1
    Ok then: They are private. `D` has no business tinkering with them. `D` is not a friend of `C` which is how the access is tried out. – Ted Lyngmo Jun 21 '20 at 00:09
  • 1
    Does [What are access specifiers? Should I inherit with private, protected or public?](https://stackoverflow.com/questions/5447498/what-are-access-specifiers-should-i-inherit-with-private-protected-or-public) answer your question? – Ted Lyngmo Jun 21 '20 at 00:18
  • `D` is a friend of `A`, but is not a friend of `C`. `D` doesn't have access to the `A` base class subobject of `C`, and so can't access any of that subobject's members, either. – Igor Tandetnik Jun 21 '20 at 01:17
  • 1
    **`C` restricts the public access to `A` by protected derivation** thus at that point nothing from `A` is visible from the public which is the way `f2` access `c` object. Either, `C` should derive publicly from `A` or specify `D` as a friend. – Phil1970 Jun 21 '20 at 02:21
  • 1
    By the way, you would have an error access to `a.z` from `f2` because of protected derivation. Because of protected derivation, it is now `C` that can grant friendship to it base class. Essentially, if you use protected or private derivation, for access purpose, it would be essentially the same thing as declaring a protected or private member of that type. The main difference would be simpler access `c.z` with derivation instead of `c.a.z` if C would have a member `protected: A a;`. – Phil1970 Jun 21 '20 at 02:30
  • @Phil1970: I agree with you that C doesn't grant friendship to D but D is a friend of A thus D can access the A's sub-object of C in one of its member functions or friends. – Maestro Jun 21 '20 at 21:07
  • @Maestro Here you have `friend` that give access and `protected` that restrict access. As with many security system, your final access would be denied. Some real life example: house key + alarm code, debit card and NIP, file and computer access, username and password… In all of those cases, if you have only one part, you won't access to the associated ressource (that require both). – Phil1970 Jun 21 '20 at 21:51

0 Answers0