我想将我的Foo类对象的Resize方法作为glutReshapeFunc()的参数传递但是我得到了这个错误。 我应该如何通过它?
这是我对Resize的定义:
class Foo{
public:
void Resize(int w, int h);
...
}
这就是我尝试调用它的方式
glutReshapeFunc(foo->Resize);
当foo不是指针时,没关系,我用来传递foo.Resize并且它有效。
提前致谢
答案 0 :(得分:4)
非静态函数采用额外的隐藏参数(this
),因此它们与具有明显相似签名的全局非成员函数不兼容。
你可以让Resize
成为一个静态的,但是你在找出要采取行动的对象时会遇到问题。 glutReshapeFunc
提及
在回调之前,当前 窗口设置为具有的窗口 被重塑了。
所以你可以从静态成员那里开始。
答案 1 :(得分:4)
foo->Resize
本身不是C ++中的有效表达式。因此,您的代码无效。在C ++中获取指向非静态成员函数的指针的唯一方法是显式使用&
运算符并显式使用成员函数的限定名称。在您的情况下,&Foo::Resize
。
然而,这一切都是重点,因为你显然需要一个指向普通函数的指针而不是成员函数。指向成员函数的指针是完全不同的对象,甚至与指向普通函数的指针远程相似。换句话说,你想做的事情是不可能的。无论你做什么,都无法将指针传递给Foo::Resize
到glutReshapeFunc
。
如果要将非静态成员函数作为回调调用,则您有责任使用某种中间包装函数来接收调用,并通过适当的对象将其委托给成员函数。 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在上面所说的问题。这可确保该方法始终可用。