你的函数是一个类的成员。当您执行类似的操作Car c; c.drive()
时,该drive()
功能需要使用汽车。那是this
指针。因此,如果 glut 没有汽车可以工作,它就无法调用该函数,它期待一个免费的函数。
您可以制作您的功能static
,这意味着该功能不适用于汽车。glut 然后就可以调用它,但是我假设您想操纵汽车。解决方案是让函数将其调用传递给对象,如下所示:
void key_press(int key, int x, int y)
{
activeCar->KeyPress(key, x, y);
}
activeCar
一些全局可访问的汽车指针在哪里。你可以用某种CarManager
单例来做到这一点。
CarManager 跟踪正在控制的活动汽车,因此当按下一个键时,您可以传递它:CarManager::reference().active_car().KeyPress(key, x, y)
.
单例是只有一个全局可访问实例的对象。它超出了答案的范围,但您可以通过 Google 搜索各种资源来创建一个。查找 Meyers Singleton 以获得简单的单例解决方案。
另一种方法是使用一种 InputManager 单例,该管理器将跟踪它应该通知按键的对象列表。这可以通过几种方式完成,最简单的是这样的:
class InputListener;
class InputManager
{
public:
// ...
void register_listener(InputListener *listener)
{
_listeners.push_back(listener);
}
void unregister_listener(InputListener *listener)
{
_listeners.erase(std::find(_listeners.begin(), _listeners.end(), listener));
}
// ...
private:
// types
typedef std::vector<InputListener*> container;
// global KeyPress function, you can register this in the constructor
// of InputManager, by calling glutSpecialFunc
static void KeyPress(int key, int x, int y)
{
// singleton method to get a reference to the instance
reference().handle_key_press(key, x, y);
}
void handle_key_press(int key, int x, int y) const
{
for (container::const_iterator iter = _listeners.begin();
iter != _listenders.end(), ++iter)
{
iter->KeyPress(key, x, y);
}
}
container _listeners;
};
class InputListener
{
public:
// creation
InputListener(void)
{
// automatically add to manager
InputManager::reference().register_listener(this);
}
virtual ~InputListener(void)
{
// unregister
InputManager::reference().unregister_listener(this);
}
// this will be implemented to handle input
virtual void KeyPress(int key, int x, int y) = 0;
};
class Car : public InputListener
{
// implement input handler
void KeyPress(int key, int x, int y)
{
// ...
}
};
当然,如果这没有意义,请随时提出更多问题。