如何在C ++和OpenGL中将类方法作为另一个函数的参数传递?

时间:2010-03-23 00:27:07

标签: c++ opengl methods glut

我知道这件事有效:

void myDisplay()
{
...
}
int main()
{
...
glutDisplayFunc(myDisplay)
...
}

所以我尝试将myDisplay()函数包含到我创建的类中。因为我希望将来用不同的类重载它。但是,编译器抱怨

argument of type 'void (ClassBlah::)()' does not match 'void(*)()' .

以下是我尝试制作的内容:

class ClassBlah
{
   ....
   void myDisplay()
   ....
}
......
int main()
{

    ...
    ClassBlah blah
    glutDisplayFunc(blah.myDisplay)
    ...
}

有人知道如何解决这个问题吗?非常感谢。

5 个答案:

答案 0 :(得分:9)

首先,非静态成员函数中有一个隐含的“this”指针,因此您需要将void myDisplay()中的ClassBlah更改为静态。解决这个限制是很尴尬的,这就是为什么C ++ faq lite说don't do it

然后,您应该能够将函数传递给ClassBlah::myDisplay

根据你的重载动机(即你要在运行时进出热插拔实现,还是只在编译时?)你可能会考虑一个实用程序“handler”静态类,它包含指向你的基类的指针,以及通过该代表承担责任。

答案 1 :(得分:5)

我遇到了自己编写C ++ Glut引擎的问题。以下是我如何解决这个问题:

我将它们放在program.cpp / main.cpp

的顶部
// Function prototypes
void doRendering( void );
void processMouse( int, int ) ;
void processMouseClick(int button, int state, int x, int y);
void keyboardInput(unsigned char c, int x, int y);

在这里将这些函数分配给过剩的回调:

glutDisplayFunc(doRendering);
glutIdleFunc(doRendering);
glutPassiveMotionFunc(processMouse);
glutMotionFunc(processMouse);
glutMouseFunc(processMouseClick);
glutKeyboardFunc(keyboardInput);

创建我自己的类,它自己处理这些,然后使我们的静态函数的内容只调用这个类的实例上的方法。你的main函数应该在main中创建一个新的类实例(在我的例子中是...... App * newApp)。

void doRendering( void )
{
    newApp->updateScene();
    newApp->drawScene();
}

void processMouse(int x, int y)
{
    newApp->processMouse(x, y);
}

void processMouseClick(int button, int state, int x, int y)
{
    newApp->processMouseClick(button, state, x, y);
}

void keyboardInput(unsigned char c, int x, int y)
{
    newApp->keyboardInput(c, x, y);
}

希望能够解释它。

答案 2 :(得分:3)

我解决这个问题的方法很简单:
首先在主函数之前做一个指针 在main函数的开头设置指向您的类实例的指针 然后在新定义的渲染函数中,您可以使用全局指针访问对象。

/**
       Class argon is defined in external header file.
*/

Argon *argonPtr;

void renderScene();

int main()
{      
   Argon argon;
   argonPtr = &argon;

   glutDisplayFunc( render );  
}

void render()
{
   RenderStuff();
   argonPtr->Render();  
}

希望它适合你,对我而言。

答案 3 :(得分:1)

您可以对成员函数使用Boost绑定,例如在成员函数上创建一个线程:

class classA
{
public:
    void memberThreadFunc(int i);
};

void main()
{
    classA a;
    boost::thread( boost::bind(&classA::memberFunc, &a, 123) );
}

答案 4 :(得分:0)

你做不到。 glutDisplayFunc采用void(*)()类型的参数,而不是void (ClassBlah::)()。除非你愿意并且能够改变过剩的来源,否则你运气不好。


许多使用回调的C API将用户指定的void*参数传递给回调,您可以使用该参数存储指向您的类的指针。然后,您可以传递一个自由函数,该函数将用户数据转换为类指针,然后调用成员函数。然而,设计过剩的方式不允许这样做。