On this topic, the C++03 standard states (emphasis mine):
11.5 Protected member access
1 When a friend or a member function of a
derived class references a protected nonstatic member function or
protected nonstatic data member of a base class, an access check
applies in addition to those described earlier in clause
11. Except when forming a pointer to member (5.3.1), the access
must be through a pointer to, reference to, or object of the derived
class itself (or any class derived from that class) (5.2.5).
What you are doing here, however, is trying to access through a pointer to the base class, which is illegal. If you change the signature to
int func(B* p) // instead of A*
you will find that it now compiles normally.
This is also the reason why you can access a without trouble from inside class B: the access is made through the implicit pointer this, which is of type B* (the derived class again). If you tried this:
A* parent = static_cast<A*>(this);
int x = parent->a; // Does not compile!
You would find that it won't compile, for the very same reason.
The converse also applies: if you downcast the pointer p to a B* you can access the protected member just fine:
class A
{
public:
// Added virtual destructor so that the class acquires a vptr,
// making dynamic_cast possible.
virtual ~A() {};
protected:
int a;
};
class B : public A
{
public:
int func(A* p)
{
// Now if we downcast p to B* we can access a just fine
// Of course if p does not actually point to a B, the
// program will have undefined behavior
int x = dynamic_cast<B*>(p)->a;
}
};
a, so what compiler and os are you using? And, what messages are produced when you compile this?ainstead ofp->a?