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
.x
is a public member ofBase
. In which case there is no issue.???
isDerivedAgain
. In which case the Derived-to-Base conversion makes sense sincetest()
hasfriend
access 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 aDerived
class, so why shouldp->x
work 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.