Why does this compile:
class FooBase
{
protected:
void fooBase(void);
};
class Foo : public FooBase
{
public:
void foo(Foo& fooBar)
{
fooBar.fooBase();
}
};
but this does not?
class FooBase
{
protected:
void fooBase(void);
};
class Foo : public FooBase
{
public:
void foo(FooBase& fooBar)
{
fooBar.fooBase();
}
};
On the one hand C++ grants access to private/protected members for all instances of that class, but on the other hand it does not grant access to protected members of a base class for all instances of a subclass.
This looks rather inconsistent to me.
I have tested compiling with VC++ and with ideone.com and both compile the first but not the second code snippet.
When
fooreceives aFooBasereference, the compiler doesn’t know whether the argument is a descendant ofFoo, so it has to assume it’s not.Foohas access to inherited protected members of otherFooobjects, not all other sibling classes.Consider this code:
If
Foo::foocan call protected members of arbitraryFooBasedescendants, then it can call the protected method ofFooSibling, which has no direct relationship toFoo. That’s not how protected access is supposed to work.If
Fooneeds access to protected members of allFooBaseobjects, not just those that are also known to beFoodescendants, thenFooneeds to be a friend ofFooBase: