如何调用父函数?

时间:2014-05-18 22:36:03

标签: c++ oop

我最近开始用C ++学习OOP概念,并尝试用类进行简单的Tic-Tac-Toe游戏。我的Game类的游戏循环从用户那里获得输入,这是我遇到这个问题的地方。我创建了一个InputHandler类,Game类有一个实例,在游戏循环中我调用inputHandler.input()。如果玩家输入"重启",我希望通过调用game.restart()重启游戏,但是我的InputHandler对象没有游戏实例。所以我目前的解决方案是通过引用传递游戏来调用InputHandler对象,这样我就可以从那里调用game.restart(),但是这对我所学到的关于OOP的一切看起来都是不好的做法。此外,对于每个与此类似的功能,我还需要通过引用传递游戏对象。我觉得我错过了一些关于OOP设计的基本知识。通过引用传递游戏对象是不是很糟糕,还是有更好的方法来解决这个问题?

//game.cpp
void Game::run() {
   while(!gameOver) {
      inputHandler.input(this);
   }
}

//inputHandler.cpp
void InputHandler::input(Game& game) {
   std::string input;
   std::cin >> input;

   if (input == "restart") {
      game.restart();
   }
}

1 个答案:

答案 0 :(得分:1)

处理特殊操作的一种方法是传递处理函数(也称为回调)。 C ++方式是std::function<void()>,可以在检测到特定事件时触发:

class SomeClass {
    ...
    std::function<void()> d_restartHandler;
public:
    void setRestartHandler(std::function<void()> handler) { d_restartHandler = handler; }
    void doSomething() {
        ...
        if (timeToRestart && this->d_restartHandler) {
            this->d_restartHandler();
        }
        ...
    }
};

函数模板std::function<Signature>实际上也可以通过合适的参数进行参数化,方法是使用合适的签名对其进行实例化。如果你觉得这种方法不是面向对象的:实际上就是这样!在内部,std::function<Signature>包含一个带有基类的层次结构,可以是一个具体的类,用于保存实际的函数对象以进行调度。你甚至可以自己实现类似的东西,但我认为这会浪费时间。

假设您拥有SomeClass实例scGame实例g,您可以使用

等注册重新启动
sc.setRestartHandler([&](){ g.restart(); });