C++ 多态性:;指向绑定函数的指针只能用于调用函数";

C++ 多态性:;指向绑定函数的指针只能用于调用函数";,c++,opengl,pointers,glut,C++,Opengl,Pointers,Glut,我将我的代码分成多个文件,但这是我不明白的一件事 在graphics.h中: ... class graphics { public: virtual void SizeMod(int w, int h); ... } 在graphics.cpp中: ... void SizeMod(int w, int h) { //Code here. } ... 在main.cpp中: ... graphics g; ... int main (int argc, char **argv) {

我将我的代码分成多个文件,但这是我不明白的一件事

在graphics.h中:

...
class graphics {
public:
virtual void SizeMod(int w, int h);
...
}
在graphics.cpp中:

...
void SizeMod(int w, int h) {
    //Code here.
}
...
在main.cpp中:

...
graphics g;
...
int main (int argc, char **argv) {
    ...
    glutReshapeFunc(g.SizeMod);
    ...
}
错误:

error C3867: 'graphics::SizeMod': function call missing argument list; use &graphics::SizeMod to create a pointer to member
于是我就这样做了:

...
graphics g;
...
int main (int argc, char **argv) {
    ...
    glutReshapeFunc(&graphics::SizeMod);
    ...
}
它仍然给我一个错误(一个不同的错误)。
有什么方法可以解决这个问题吗?

它不会以这种方式工作,因为
SizeMod
是一个非静态的类成员方法,所以需要调用
this
。您必须使
SizeMod
静态。

GLUT是一个C API<代码>函数要求对签名函数进行回调

void (int, int)
graphics::void(int, int)

一个C++类成员函数,在你的例子中图形::SizeMod有签名

void (int, int)
graphics::void(int, int)

现在,没有明确定义的C++ abi,可以严格地转换成普通的C abi,但是对于大多数编译器上的所有实用方法,上面的C++签名看起来像

void(graphics*, int, int)
如果通过一个C ABI的眼镜看

第一个
graphics*
参数是隐式
This
指针

这本质上意味着,当您将其作为回调传递给GLUTEFunction时,它会中断,因为

  • 类型不匹配
  • 没有办法通过某种方式传递实例

< >编辑:C++ LAMBDAS在这里不工作,正如Mike Dinsdale指出的。



说真的,我真的厌倦了一次又一次地回答同一个问题,一次又一次,一次又一次……这个问题每周都会被问三次。

这导致了我的链接错误。错误LNK2019:未解析的外部符号“public:static void\uu cdecl graphics::SizeMod(int,int)”(?SizeMod@graphics@@SAXHH@Z)在函数_main中引用,在cpp文件的
void SizeMod(int w,int h)
行中
SizeMod
之前放置一个
graphics::
。@MM。使用静态成员函数是不可靠的,因为调用约定在C++静态成员函数和C函数之间可能不同。@ AnNySuxIsNeN:请看我的答案,使用C++ 11 LAMBDAS的一个好的解决方案。这也解释了为什么这些东西不是“仅仅混合”的。@datenwolf:你不能在静态方法上强制使用所需的约定吗?我认为你可以。你的lambda代码似乎有一些问题:
graphics gr()
是一个MVP,你不能在lambda中捕获
gr
,最严重的是,我不认为一个带有捕获的lambda可以转换成函数指针(参见示例)。@MikeDinsdale:看起来你是对的。哦,好吧,然后回到FFAKER黑客,我建议在另一个答案中,也与C++成员函数和回调有关: