Mr Dyl wrote:
There's probably a simple explanation for this and it's just too late
for my brain to work. Does anybody know a good reason why class B2
compiles but class B1 doesn't?
....
It's because A::X is being accessed through a pointer other than a
pointer that the scope has visibility. i.e. Nested_B does not have
access to protected parts of A, but Nested_A does. B1 and B2 does have
visibility into the protected parts of A.
What's weird (and logically a hole in the standard IMHO), is that you
can take a member pointer to B1::X - which is exactly the same as A::X,
but since B1::Nested_B has visibility into B1, it can take B1::X which
the allows you to directly access A::X from an A&. See below.
Probably the best thing is to provide an accessor in Nested_A that
promotes the visibility to classes derived from Nested_A (see GetAX()
below).
class A {
public:
class Nested_A {
protected:
int & GetAX()
{
return ptrA->X;
}
A* ptrA;
};
protected:
int X;
};
class B1 : public A {
public:
class Nested_B : public Nested_A {
int foo() {return(ptrA->X);}
// error: protected member "A::X" is not accessible through a "A"
pointer or object
int foo1() {return(ptrA->*(&B1::X));}
int foo2() {return(GetAX());}
};
};
class B2 : public A {
public:
class Nested_B : public Nested_A {
int foo() {return(ptrB->X);} // Happy compiler
int foo1() {A* ptrA=ptrB; return(ptrA->X);} // UNhappy compiler
protected:
B2* ptrB;
};
};