尝试在 C++ 中执行一些 OpenGL 时出现 C2664 错误
Posted
技术标签:
【中文标题】尝试在 C++ 中执行一些 OpenGL 时出现 C2664 错误【英文标题】:C2664 error in an attempt to do some OpenGl in c++ 【发布时间】:2009-10-08 22:27:35 【问题描述】:这是我的代码摘要。我正在尝试使用 glutSpecialFunc 告诉 glut 使用我的 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
【问题讨论】:
此问题应重新标记为 Visual Studio 或 Visual-C++ 【参考方案1】:你的函数是一个类的成员。当您执行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)
// ...
;
当然,如果这没有意义,请随时提出更多问题。
【讨论】:
哇,答案很好,速度也很快!。解释了一切。【参考方案2】:我最终做的是
添加:
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++;
【讨论】:
以上是关于尝试在 C++ 中执行一些 OpenGL 时出现 C2664 错误的主要内容,如果未能解决你的问题,请参考以下文章
错误:在 Linux 上使用 OpenGL 编译 C++ 程序时出现“GL/glfw3.h:没有这样的文件或目录”
为啥在 glfw 窗口上没有使用 opengl 显示位图图像?在 C++ 中读取位图图像文件时出现问题
尝试在 Visual Studio 2013-15 中从 C++ 执行 python 脚本时出现导入错误