C++ 向成员函数传递指针的步骤

C++ 向成员函数传递指针的步骤,c++,function-pointers,glut,member-function-pointers,freeglut,C++,Function Pointers,Glut,Member Function Pointers,Freeglut,我有一个带有实例函数(或方法?)的类。在实例中,我尝试将指向这些函数的指针传递给库。库需要静态函数 当我将指针传递给回调函数时,编译器会抱怨我的函数不是静态的。我试图将它们设置为静态,但如果这样做,则无法从函数中访问实例字段 我怎么能绕过这个 类似的问题是:他们建议将该方法置于何处。但是我不能那样做,或者我不知道我怎么能做到 代码 免责声明:我刚开始C++。我读了所有的加速C++,这是我第一个尝试语言的项目。我的背景是Java。你想做的是不可能的。这实际上是glut的错误 事情是这样的: gl

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

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

我怎么能绕过这个

类似的问题是:他们建议将该方法置于何处。但是我不能那样做,或者我不知道我怎么能做到

代码
<>免责声明:我刚开始C++。我读了所有的加速C++,这是我第一个尝试语言的项目。我的背景是Java。

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

事情是这样的:

  • glut
    想要调用一个函数,而不给它提供数据
  • 您希望函数使用一些数据
这些都是相互冲突的需求。我相信
glut
决定了您可以安全地使用全局变量


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

您应该有一个
静态方法
和一个
实例
(可能是静态的)来从
静态
函数调用
实例
的成员函数

大概是这样的:

//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();
}
简言之,你不能。 C++成员函数实际上是“链接”到对象的实例。在较低的级别上,它们有一个额外的参数,实际上是指向该对象实例的指针


所以,您必须使用静态函数,并且,由于glut不允许您传递一个标识当前实例的参数,因此您必须想出一些解决方法。最简单的解决方法是使用静态成员。如果您的GlutController是单例的(我认为是单例的),那么您就没事了。

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


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

我对glut了解不多,但听起来它需要一些可调用的东西,不带任何参数(包括隐式参数)。因此,一个适当构造的
std::function
难道不起作用吗?任何开发一个不透明的库函数而不能接受用户定义的参数(例如用于回调)的人都应该被解雇,晋升到市场营销/销售部门,或者给予一个为竞争对手工作的经济激励。@Shahbaz我正在尝试做一个简单的演示,我读到glut在样板代码方面比SDL使用起来非常简单。我还用《OpenGL超级圣经》一书来指导我。“我认为使用static/global是不可避免的,或者像尼克在下面的回答中说的那样使用Singleton。”MartinJames表示同意。和。我认为在设计过剩的时候,人们不太善于预见。要么是这样,要么是microsoft参与其中。@Antoieng,您需要对SDL做的额外工作就是编写一个3行主循环并删除所有给定的回调行,以及一个
while/select
,它根据队列中的事件调用您的函数。相信我,如果你只想画几个三角形,那么过剩就很难控制了。顺便说一句,我也从同一本书中学习了openGL,但是用SDL替换glut代码,重点是openGL部分,所以它不应该妨碍您。
//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();
}
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 */ }