From C++ Primer 5th edition (D inherits from B)
Member functions and friends of classes derived from D may use the derived-tobase conversion if D inherits from B using either public or protected. Such code may not use the conversion if D inherits privately from B.
Is there any reason for this or am I meant to take it at face value? It might seem obvious why this is but it's tripping me up in one example:
#include <iostream>
using namespace std;
class Base {
public:
int x = 2;
};
class Derived : protected Base { };
class DerivedAgain : public Derived {
friend void test();
};
void test() {
??? a;
Base* p = &a;
cout << p->x;
}
int main(){
test();
}
I want to understand the accessibility of test() to the member x in derived-to-base conversions. Considering the three potential cases of the type ??? of a in function test().
???isBase.xis a public member ofBase. In which case there is no issue.???isDerivedAgain. In which case the Derived-to-Base conversion makes sense sincetest()hasfriendaccess to all members ofDerivedAgain, including those inherited indirectly fromBase. So there is no issue using a pointer to accessx.???isDerived. It compiles fine. But why? I'm confused at this point.test()doesn't have special access to the members of aDerivedclass, so why shouldp->xwork and consequently the Derived-to-Base conversion be valid? Does it work just cause?
Indeed if I change the operation of test() to
void test() {
Derived a;
cout << a.x;
}
It does not compile, as I would expect to happen - because the x member that a Derived object inherits is made protected and thus can't be used by users.
If I replace the type of a with Base and DerivedAgain the modified test() compiles fine, as I would expect it to.
I'm just confused as to why a friend function of a second-level derived class is allowed to use the first-level direct-to-base conversion, if that friend function has no special access to the first-level derived class members.