Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

accessing a protected member of a base class in another subclass

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.

like image 284
Kaiserludi Avatar asked Jul 24 '12 13:07

Kaiserludi


People also ask

Can we access protected member in another class?

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.

Can we access protected members of a class in subclass of that class present in other package?

We can access protected members of a class in its subclass if both are present in the same package.

How can a protected member of a class be accessed by its subclass in a different package illustrate with example?

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.


2 Answers

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; }; 
like image 184
Rob Kennedy Avatar answered Sep 23 '22 00:09

Rob Kennedy


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.

like image 28
h0b0 Avatar answered Sep 23 '22 00:09

h0b0