Help me understand the protected keyword

Started by
17 comments, last by King of Men 17 years, 1 month ago
I have an abstract base class which I'll call Human. It has two derived classes, call them Killer and Victim. It also has a protected member _protIntArray. Now, at one point, Killer has to take a pointer to a Victim and do something to its _protIntArray, thusly:

void Killer::kill (VictimListWithExtraInfo* victs) {
  victs->theVictimList[0]->_protIntArray[0] += 5;
}
If I understand the documentation correctly, Killer, being a subclass of Human, should be able to access protected members of Human through a pointer to another subclass of Human. Right? (I'm getting this from here.) But my compiler (gcc 3.2.3) gives me this: Human.hh:70: `IntArrayWrapper Human::_protIntArray' is protected Killer.cc:68: within this context What am I misunderstanding, here?
To win one hundred victories in one hundred battles is not the acme of skill. To subdue the enemy without fighting is the acme of skill.
Advertisement
Use a Human pointer instead of a Killer or Victim pointer.
Hum. I tried that with an explicit cast, thus:

void Killer::kill (VictimListWithExtraInfo* victs) {  ((Human*) (victs->theVictimList[0]))->_protIntArray[0] += 5;}


but I'm still getting the same error.
To win one hundred victories in one hundred battles is not the acme of skill. To subdue the enemy without fighting is the acme of skill.
Killer being a subclass of human means that killer does indeed inherit the protected member. This means that an instance of killer has the member _protIntArray. It can access it's own _protIntArray. It can not access the protected or private members of another instance.

Ah, ok, now I get it. I'll make it a protected accessor method instead. Thanks!
To win one hundred victories in one hundred battles is not the acme of skill. To subdue the enemy without fighting is the acme of skill.
Quote:Original post by shengshwi
Killer being a subclass of human means that killer does indeed inherit the protected member. This means that an instance of killer has the member _protIntArray. It can access it's own _protIntArray. It can not access the protected or private members of another instance.


while the behavior you are seeing seems like what shengshwi is describing ... that is not he behavior I am used to or believe is correct.

if this is correct:

class A  protected:    int i;  public:    void DoSomething(A &rhs)      {        i += rhs.i;  // accessing another instances i directly      }

why wouldn't this be correct:
class B : public A  public:    void DoSomethingElse(B &rhs)      {        i += rhs.i;  // accessing another instances i directly      }

I thought a derived class could internally do with protected members from its base, the same thing it can do with private members of itself?

Is this not correct?
also, if it cannot access "rhs.i", it wouldn't be able to access a protected method on rhs either "rhs.SomeProtectedFunc()" would fail too, because there is no difference in C++ between data members and method members (that I am aware of).

I guess if the access to rhs.??? was inside of the function you put in the base class, then it could work even if the above fails.
Quote:Original post by Xai
I thought a derived class could internally do with protected members from its base, the same thing it can do with private members of itself?

Is this not correct?


It is. However, based on his question and code, I believe he has a setup like this:

class A{protected:     int i;};class B : public A{};class C : public A{public:     void doSomething(B b)     {          b.i = 5; //Error here     }};


Inherited protected members remain protected; as such, other classes can't access them, even if the two classes are part of the same inheritance hierarchy.
------------------------------Support the Blue Skies in Games Campaign!A blog... of sorts.As a general rule, if you don't have a general rule in your signature, you aren't as awesome as someone who does. General rules roxor teh big one one ones.
I suspect the OP has a hierarchy like this

class Human{protected:    int value;};class Killer : public Human{public:    void updateValue()     {         value++;     }};class Victim : public Human{public:    void updateValue()     { 	value++; // ok. updating local value    }    void updateKillerValue(Killer& killer)     {         killer.value++; // error. Victim does not inherit Killer so this is not protected on our behalf.        // This does not work either even if we do inherit Human	Human* h = (Human*)&killer;	h->value++;    }};


I have to say Im a bit confused myself.
Ok, so now I understand what's going on. Is there any way, though, to give the whole inheritance hierarchy access to each others' protected parts, without going whole hog and making them public? And preferably without horrible kludges like declaring them all friends of each other.
To win one hundred victories in one hundred battles is not the acme of skill. To subdue the enemy without fighting is the acme of skill.

This topic is closed to new replies.

Advertisement