传递指向成员函数的指针

时间:2012-08-03 09:07:17

标签: c++ function-pointers glut member-function-pointers freeglut

我有一个带有实例函数(或方法?)的类。在一个实例中,我尝试将指向这些函数的指针传递给库。该库需要静态函数。

当我将指针传递给回调函数时,编译器会抱怨我的函数不是静态的。我试图将它们设为静态,但如果我这样做,那么我就无法从函数中访问实例字段。

我怎么能绕过这个?

类似的问题是:Using a C++ class member function as a C callback function他们建议将方法设置为静态。但是我做不到,或者我不知道我怎么做。

代码

GlutController::GlutController (int argc, char **argv) {

   // stuff ..

   // Register callbacks
   glutSpecialFunc( OnSpecialKeys );  // Error, need static functions
   glutReshapeFunc( OnChangeSize );   // Error...
   glutDisplayFunc( OnRenderScene );  // Error...

   // stuff ..
}

GlutController::~GlutController() {

}

void GlutController::OnChangeSize(int aNewWidth, int aNewHeight){

   glViewport(0,0,aNewWidth, aNewHeight);
   mViewFrustrum.SetPerspective( APP_CAMERA_FOV,             // If this function is 
            float( aNewWidth ) / float( aNewHeight ),        // static, this won't 
            APP_CAMERA_NEAR,                                 // work
            APP_CAMERA_FAR );
   mProjectionMatrixStack.LoadMatrix(                        // Same here
            mViewFrustrum.GetProjectionMatrix() );
   mTransformPipeline.SetMatrixStacks(mModelViewMatrixStack, // Same here  
            mProjectionMatrixStack);

}

void GlutController::OnRenderScene(void){
   mGeometryContainer.draw();                                // Won't work if static
}

void GlutController::OnSpecialKeys(int key, int x, int y){
   mGeometryContainer.updateKeys(key);                       // Won't work if static
}

免责声明:我刚开始使用C ++。我阅读了所有Accelerated C ++,这是我尝试该语言的第一个项目。我的背景是Java。

4 个答案:

答案 0 :(得分:7)

你想做的事是不可能的。实际上这是glut的错误。

事情就是这样:

  • glut想要调用一个函数,而不给它提供数据,
  • 您希望您的功能使用一些数据,

这是相互冲突的需求。我相信glut决定你可以安全地使用全局变量。

因此,一种解决方案是使用静态函数,使用静态数据。或者更好的解决方案是切换到SDL

答案 1 :(得分:3)

总之,你不能。 C ++成员函数实际上是“链接”到对象的实例。在较低级别,它们有一个额外的参数,实际上是指向该对象实例的指针。

所以,你必须使用静态函数,并且,由于过剩不允许你传递一个可以识别当前实例的参数,你将不得不提出一些解决方法。最简单的解决方法是使用静态成员。如果你的GlutController是单身(我认为是),你会没事的。

答案 2 :(得分:2)

使用指向GlutInstance的文件范围静态变量是可能且显然是安全的(静态函数+静态数据,如另一个答案中所述)。

static GlutController* s_this;

static void s_OnChangeSize(int w, int h) { s_this->OnChangeSize(w, h); }

GlutController::GlutController (int argc, char **argv) { 
   s_this = this;

   glutSpecialFunc(s_OnSpecialKeys);
}

GlutController::~GlutController() { s_this= 0; } 

void GlutController::OnChangeSize(int w, int h) { /* non-static stuff */ }

s_this仅在本地文件中可见,例如对于从另一个文件调用GlutController构造函数的任何代码都不可见。

答案 3 :(得分:1)

您应该static methodinstance(可能是静态的)从instance函数

调用static的成员函数

这样的事情:

//static method
void MyClass::myCallback()
{
    static MyClass instance; //or you can store your in instance in some Singleton, or
    //possibly create a temporary
    instance.nonStaticMethod();
}