-1

I have a setup something along the lines of this. Multiple levels of inheritance from a single base class containing a protected member x.

class Sprite {
protected:
    float x, y;
}

class AnimatedSprite : Sprite {
public:
    void draw(float x, float y);
}

class Player : AnimatedSprite {
public:
    void draw(float x, float y);
}

The implementation for the method draw in derived class Player is something along these lines.

void Player::draw(float x, float y) {
    AnimatedSprite::draw(this->x, this->y);
}

However compiler is complaining that members x and y are inaccessible, even though they are listed as protected in the base class.

  • Why do you use private inheritance? – curiousguy Oct 01 '15 at 20:22
  • 2
    @curiousguy: Because he didn't know about the default inheritance level for classes, I assume. – Christian Hackl Oct 01 '15 at 20:24
  • "_compiler is complaining_" then you should probably post the error message instead of paraphrasing it – curiousguy Oct 01 '15 at 20:26
  • @curiousguy because in my honest opinion my simplified explanation of the error provides the same information that the actual error message would provide however in a much more readable format. Will keep in mind for next time though. – Matt Gilene Oct 01 '15 at 20:42

2 Answers2

4

Derivation for a class is private by default. If you want to access the protected base members, then you must make the derivation public:

class AnimatedSprite : public Sprite

// ...

class Player : public Sprite

(You could also make the derivation protected, but that would be a rather exotic thing to do. You could likewise make the first derivation public or protected and leave the second one private, but that would not match the supposed intention of the class hierarchy. public inheritance is clearly what you are looking for in both cases.)

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
  • "_then you must make the derivation public_" Why? – curiousguy Oct 01 '15 at 20:26
  • @curiousguy: Yes, you could also make the first derivation `public` and the second `private`. Given the class names and the supposed intention, this would of course be exactly as exotic as `protected` inheritance. I'll still add it to the answer for the sake of completeness. – Christian Hackl Oct 01 '15 at 20:29
3

AnimatedSprite uses private inheritance, so the members of Sprite become private members of AnimatedSprite. You might want to use protected inheritance:

class AnimatedSprite : protected Sprite {
public:
    void draw(float x, float y);
}

class Player : protected AnimatedSprite {
public:
    void draw(float x, float y);
}
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • 3
    Better would be public inheritance, as I assume `AnimatedSprite` and `Player` both have an *is-a* relationship with `Sprite`. – rlbond Oct 01 '15 at 20:11
  • 1
    May be you are the one of those I've been looking for for the last 15 or so years and can explain why on earth do we need protected inheritance? – SergeyA Oct 01 '15 at 20:11
  • That fixed it! Thanks for the help. – Matt Gilene Oct 01 '15 at 20:11
  • @ribond Oh yeah, you're right. One probably would want to be able to use an `AnimatedSprite` as a `Sprite`. – Brian Bi Oct 01 '15 at 20:12