在C ++中具有多重继承的奇怪的多态行为?

时间:2012-10-14 15:52:14

标签: c++ polymorphism sdl multiple-inheritance

所以,我正在使用SDL写一个小Pong游戏克隆,我有以下设置。

有一个通用游戏类SlimGame,它继承自FSM类和事件处理程序类:

// DEFINITION
class SlimGame : public SlimFSM, public SlimEventHandler {
protected:
  bool    running;        // indicates if the game is running

public:
  bool isRunning() { return this->running; }
  void setRunning(bool r) { this->running = r; }

  void run();                         // encapsulates the game loop
};

// IMPLEMENTATION
void SlimGame::run() {
  SDL_Event event;

  this->setRunning(true);

  while(this->isRunning()) {
      while(SDL_PollEvent(&event)) {
          this->handleEvent(&event);
          std::cout << "MAIN LOOP Running: " << this->isRunning(); << endl;
      }

      // ...
  }
}

FSM类与奇怪的行为无关,但事件处理程序类如下所示:

// DEFINITION
class SlimEventHandler {
public:
  SlimEventHandler() { }
  virtual ~SlimEventHandler() { }

  void handleEvent(SDL_Event *event);

  virtual void onExit();
};

// IMPLEMENTATION
void SlimEventHandler::handleEvent(SDL_Event *event) {
  switch(event->type) {
    case SDL_QUIT:
      this->onExit();
      break;
  }
}

void SlimEventHandler::onExit() {
  std::cout << "PARENT onExit!" << std::endl;
}

然后我的PongGame类本身继承自SlimGame(因此间接来自SlimFSMSlimEventHandler):

// DEFINITION
class PongGame : public SlimGame {
public:
  PongGame();
  ~PongGame();

  void onExit();
};

// IMPLEMENTATION
void PongGame::onExit() {
  this->setRunning(false);

  std::cout << "CHILD onExit!" << std::endl;
}

因此,通过这种设置,我可以像这样运行我的游戏并启动它,很好:

int main(int argc, char **argv) {
  PongGame game;

  // setup

  game.run();

  // tear down

  return 0;
}

然而,事件处理并不像它应该的那样工作。如果单击窗口关闭按钮,SDL_QUIT事件将被触发,方法handleEvent将被调用。这很好,但是方法本身调用它自己的onExit,而不是PongGame类的继承方法,所以我看到了:

PARENT onExit!

在控制台而不是

CHILD onExit!

不应该调用PongGame中的派生方法,而不是SlimEventHandler中的虚拟空实现吗?

1 个答案:

答案 0 :(得分:0)

您应该将run()方法声明为virtual,以强制将对象指针解释为PongGame对象,因为目前它不是。某些编译器可能会警告您也要覆盖run()。在这种情况下,run()的PongGame实现可以是一个简单的代码重复,大部分时间都是无害的。

void PongGame::run() {
    SlimGame::run();
}