【发布时间】:2012-10-04 17:35:35
【问题描述】:
所以,我正在使用 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(因此间接继承自SlimFSM 和SlimEventHandler):
// 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中的虚空实现吗?
【问题讨论】:
-
我在一些类中存根来编译你的代码,我确实看到“CHILD onExit”,所以问题似乎出在其他地方。
-
有趣。这可能是在库中拆分代码的问题吗?我正在使用 Mac OSX,除了
PongGame类之外的所有内容都在静态库中...... -
这应该没什么区别。
-
我将
run方法移到PongGame类中,现在它可以工作了,这很好,但不是我想要的抽象级别......非常非常奇怪! -
尝试使 SlimEventHandler::onExit() 成为纯虚拟的。这可能会导致编译错误,从而使问题更加明显。
标签: c++ polymorphism sdl multiple-inheritance