【问题标题】:Unable to access protected member from derived class无法从派生类访问受保护的成员
【发布时间】:2015-12-30 00:04:25
【问题描述】:

我有一个类似的设置。从包含受保护成员 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);
}

派生类 Player 中的方法 draw 的实现是这样的。

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

但是编译器抱怨成员 x 和 y 不可访问,即使它们在基类中被列为受保护。

【问题讨论】:

  • 为什么要使用私有继承?
  • @curiousguy:我猜是因为他不知道类的默认继承级别。
  • "编译器在抱怨" 那么你应该发布错误消息而不是解释它
  • @curiousguy 因为老实说,我对错误的简化解释提供了与实际错误消息相同的信息,但格式更易读。不过下次会记住的。

标签: c++ member protected


【解决方案1】:

AnimatedSprite 使用私有继承,所以Sprite 的成员成为AnimatedSprite 的私​​有成员。您可能想要使用受保护的继承:

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

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

【讨论】:

  • 更好的是公共继承,因为我假设AnimatedSpritePlayer 都与Sprite 具有is-a 关系。
  • 也许你就是我在过去 15 年左右一直在寻找的人之一,并且可以解释为什么我们需要受保护的继承?
  • 解决了!感谢您的帮助。
  • @ribond 哦,是的,你是对的。人们可能希望能够将AnimatedSprite 用作Sprite
【解决方案2】:

class 的派生默认为private。如果要访问protected 基成员,则必须进行派生public

class AnimatedSprite : public Sprite

// ...

class Player : public Sprite

(您也可以进行推导 protected,但这将是一件相当奇特的事情。您同样可以进行第一个推导 publicprotected 并留下第二个推导 private ,但这与类层次结构的预期意图不符。public 继承显然是您在两种情况下都在寻找的。)

【讨论】:

  • "那么你必须公开推导" 为什么?
  • @curiousguy:是的,您也可以进行第一个推导public 和第二个推导private。鉴于类名和假定的意图,这当然与protected 继承一样奇特。为了完整起见,我仍会将其添加到答案中。