类型'(Foo ::)(int,int)'的参数与main.cpp中的'void(*)(int,int)'不匹配

时间:2010-10-25 17:56:37

标签: c++ glut

我想将我的Foo类对象的Resize方法作为glutReshapeFunc()的参数传递但是我得到了这个错误。 我应该如何通过它?

这是我对Resize的定义:

class Foo{
    public:
    void Resize(int w, int h);
    ...
}

这就是我尝试调用它的方式

glutReshapeFunc(foo->Resize);

当foo不是指针时,没关系,我用来传递foo.Resize并且它有效。

提前致谢

4 个答案:

答案 0 :(得分:4)

非静态函数采用额外的隐藏参数(this),因此它们与具有明显相似签名的全局非成员函数不兼容。

你可以让Resize成为一个静态的,但是你在找出要采取行动的对象时会遇到问题。 glutReshapeFunc提及

  

在回调之前,当前   窗口设置为具有的窗口   被重塑了。

所以你可以从静态成员那里开始。

答案 1 :(得分:4)

foo->Resize本身不是C ++中的有效表达式。因此,您的代码无效。在C ++中获取指向非静态成员函数的指针的唯一方法是显式使用&运算符并显式使用成员函数的限定名称。在您的情况下,&Foo::Resize

然而,这一切都是重点,因为你显然需要一个指向普通函数的指针而不是成员函数。指向成员函数的指针是完全不同的对象,甚至与指向普通函数的指针远程相似。换句话说,你想做的事情是不可能的。无论你做什么,都无法将指针传递给Foo::ResizeglutReshapeFunc

如果要将非静态成员函数作为回调调用,则您有责任使用某种中间包装函数来接收调用,并通过适当的对象将其委托给成员函数。 C ++本身没有提供很好的功能,但它通常可以使用您尝试使用的库的特定功能来实现(假设库的设计考虑到了这一点)。

答案 2 :(得分:2)

您需要将当前窗口映射到表示该窗口的foo对象(假设每个窗口有一个foo对象)。

如果您只有一个foo对象,或者您想让该方法保持静态,那么请停止。这是一个C库,因此不了解C ++ ABI。将代码切换回使用C函数。如果您的代码是用C ++文件编写的(或编译为C ++),那么您必须将函数声明为 extern“C”,以确保绑定正确。

如果每个窗口都有一个Foo对象,那么我会这样做:

std::map<int,Foo*>   myFoo;

extern "C" void myWindowRsize(int width, int height);

myInitGlut()
{
    // Do Init stuff
    glutReshapeFunc(&myWindowRsize);
}

myCreateWindow(std::string const& name)
{
    // When a window is created store the mapping:
    winID =  glutCreateWindow(name.c_str());

    // Now we have a new Foo for each window
    // Note this code is not complete myFoo should manage the objects this suggests
    // using a container of smart pointers or a smart container see boost for details.
    myFoo[winID] = new Foo();
}

// Your static resize function called for all windows
void myWindowRsize(int width, int height)
{
    // Get the current window. Then get the foo object for that windows.
    int   currentWindow = glutGetWindow();
    Foo*  windowsFoo    = myFoo[currentWindow];

    // Call your resize method.
    windowsFoo->Resize(width, height);
}

答案 3 :(得分:2)

简单地向函数添加静态可以解决Remus Rusanu在上面所说的问题。这可确保该方法始终可用。