11

我知道这件事有效:

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)
    ...
}

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

4

5 回答 5

9

首先,在非静态成员函数中有一个隐式的“this”指针,所以你需要将你的void myDisplay()in更改ClassBlah为静态的。解决这个限制很尴尬,这就是 C++ faq lite 说不要这样做的原因

然后,您应该能够将函数作为ClassBlah::myDisplay.

根据您重载的动机(即您是要在运行时进出热插拔实现,还是仅在编译时?)您可能会考虑一个实用程序“处理程序”静态类,其中包含指向您的基类的指针,并通过委派责任那。

于 2010-03-23T00:31:37.397 回答
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);

在此处将这些函数分配给 glut 的回调:

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);
}

希望能解释一下。

于 2010-03-23T01:19:38.440 回答
3

我解决这个问题的方法很简单:
首先在 main 函数之前创建一个指针。
在 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();  
}

希望它对你有用,对我有用。

于 2013-11-14T12:07:09.157 回答
1

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

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

void main()
{
    classA a;
    boost::thread( boost::bind(&classA::memberFunc, &a, 123) );
}
于 2010-03-23T00:55:31.427 回答
0

你不能。glutDisplayFunc接受类型的参数void(*)(),而不是void (ClassBlah::)()。除非你愿意并且能够改变过剩的来源,否则你就不走运了。


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

于 2010-03-23T01:10:15.297 回答