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.
Protected members in a class are similar to private members as they cannot be accessed from outside the class. But they can be accessed by derived classes or child classes while private members cannot.
We can access protected members of a class in its subclass if both are present in the same package.
Protected Access Modifier - Protected Variables, methods, and constructors, which are declared protected in a superclass can be accessed only by the subclasses in other package or any class within the package of the protected members' class. The protected access modifier cannot be applied to class and interfaces.
When foo
receives a FooBase
reference, the compiler doesn't know whether the argument is a descendant of Foo
, so it has to assume it's not. Foo
has access to inherited protected members of other Foo
objects, not all other sibling classes.
Consider this code:
class FooSibling: public FooBase { }; FooSibling sib; Foo f; f.foo(sib); // calls sib.fooBase()!?
If Foo::foo
can call protected members of arbitrary FooBase
descendants, then it can call the protected method of FooSibling
, which has no direct relationship to Foo
. That's not how protected access is supposed to work.
If Foo
needs access to protected members of all FooBase
objects, not just those that are also known to be Foo
descendants, then Foo
needs to be a friend of FooBase
:
class FooBase { protected: void fooBase(void); friend class Foo; };
The C++ FAQ summarizes this issue nicely:
[You] are allowed to pick your own pockets, but you are not allowed to pick your father's pockets nor your brother's pockets.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With