Accessing protected members from a derived class

Feb 20, 2009 at 11:56pm
Hi, based on a short amount of research, I've learned that the following code is illegal in C++
1
2
3
4
5
6
7
8
9
class Base {
protected:
  int i;
};

class Derived : public Base {
  int f(Base* b) { return b->i; }    // <- illegal
  int g(Derived* d) { return d->i; } // <-- works
};


What I don't understand here, is why a inside of Derived, you cannot access a protected member of Base from an instance of a Base, but you can from an instance of Derived. This seems counter to the ideas of OO, as all instances of any type of Base should be treatable as Bases, and anything in Base's interface (in this case, the protected interface which is accessable by Derived) should be accessable from any Base.
That said, I have two questions:
#1, why is this not allowed, when it is in other languages (at least Java)? The only thing I can really imagine is having a protected function used for something (like a Template Method), where an evildoing subclasser could make that function mean something else, but that's true for a lot of things in C++.
#2, is there any way to get around this without hacking (i.e., making "i" public-- even though it doesn't make sense to be in Base's public abstraction, or making Derived a friend of Base-- which wouldn't be scalable since you might not even have access to the base class's source down the road)?
Last edited on Feb 20, 2009 at 11:56pm
Feb 21, 2009 at 12:50am
Are you sure you mean protected and not private? What you are describing above sounds right if i were private.

Private members are not accessible directly by derived classes, but protected members are.
Feb 21, 2009 at 12:53am
I'm sure. The example I wrote I took almost directly from a C++ documentation site.

If "i" were a private member of Base, NOTHING written in Derived would have access to it.
Feb 21, 2009 at 12:59am
Have you tried compiling the above example? It looks like it should compile to me. (I don't have a compiler on this machine).
Feb 21, 2009 at 1:18am
I compiled it and verified the results (I didn't believe it, myself!). It seems peculiar. I initially thought that maybe it's because the pointers could be to another object, as if to access the member i from "outside". Oddly enough, though, it does work in the case of method g.
Last edited on Feb 21, 2009 at 1:19am
Feb 21, 2009 at 1:24am
Ok; found it. According to The C++ Programming Language (Sp. Ed.) by Bjarne Stroustrup on page 404:

"A derived class can access a base calss' protected members only for objects of its own type [...] This prevents subtle errors that would otherwise occur when one derived class corrupts data belonging to other derived classes."
Last edited on Feb 21, 2009 at 1:27am
Feb 21, 2009 at 3:53am
Uh-huh...

For example, if there was a Derived2 class, Derived would be able to modify their data if protected worked as OP expected.
Feb 21, 2009 at 5:21am
I don't know about you, but I would expect that if a variable was defined in a Base class, it should have a singular meaning and all subclasses should expect to use it in the same way. Furthermore, who's to say if somebody subclassed Derived into VeryDerived, and VeryDerived used i in a totally different fashion, that would be just as "corrupting."
It also bothers me that this is true for protected methods of Base even more. I can almost understand not allowing you to edit another class's variables, but there's very little corruption that could be had, unless the other class is purposefully going out of their way to make their version of the method do something different than originally intended, but that's just an awful practice to begin with. C++ doesn't usually work under the assumption "assume the worst case scenario and protect the coder when the majority of the time the syntax is meaningful and useful" and I don't see why they're doing it here.
Topic archived. No new replies allowed.