这是我的代码摘要。我正在尝试使用glutSpecialFunc告诉过剩使用我的KeyPress功能
class Car : public WorldObject
{
public:
void KeyPress(int key, int x, int y)
{
}
Car()
{
glutSpecialFunc(&Car::KeyPress); // C2664 error
}
}
我得到的错误信息是:
Error 1 error C2664: 'glutSpecialFunc' : cannot convert parameter 1 from 'void (__thiscall Car::* )(int,int,int)' to 'void (__cdecl *)(int,int,int)' c:\users\thorgeir\desktop\programmingproject1\quickness\quickness\car.cpp 18 Quickness
答案 0 :(得分:2)
您的函数是类的成员。当您执行Car c; c.drive()
之类的操作时,drive()
函数需要使用汽车。那是this
指针。如果没有汽车可以使用,那么过剩就无法调用该函数,它期待一个自由函数。
你可以使你的功能static
,这意味着该功能不能在汽车上运行。然后过剩可以称之为,但我认为你想操纵一辆车。解决方案是让函数将调用传递给对象,如下所示:
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)
{
// ...
}
};
如果没有意义,当然可以随意提出更多问题。
答案 1 :(得分:0)
我最终做的是
添加:
virtual void KeyPress(int key, int x, int y) {};
到WorldObject类
将事件发送给汽车。
void KeyPressed(int key, int x, int y)
{
KeyPress(key,x,y);
list<WorldObject*>::iterator iterator = ChildObjects.begin();
while(iterator != ChildObjects.end())
{
(*iterator)->KeyPressed(key,x,y);
iterator++;
}
}