代码之家  ›  专栏  ›  技术社区  ›  nacho4d

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

  •  1
  • nacho4d  · 技术社区  · 14 年前

    我想将foo类对象的resize方法作为glutriformefunc()的参数传递,但我得到了这个错误。 我该怎么通过?

    这是我对调整大小的定义:

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

    我就是这样称呼它的

    glutReshapeFunc(foo->Resize);
    

    当foo不是指针的时候没关系,我用它来传递foo.resize和它工作。

    提前谢谢

    4 回复  |  直到 12 年前
        1
  •  4
  •   Remus Rusanu    14 年前

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

    你可以做 Resize 一个静态的,但是你会有一个问题,在什么对象上行动。 glutReshapeFunc 提到

    在回调之前, 现在的 窗口 设置为 已重新整形。

    所以可以从静态成员中开始。

        2
  •  4
  •   AnT stands with Russia    14 年前

    foo->Resize 本身不是C++中的一个有效表达式。所以,您的代码完全无效。获得C++中非静态成员函数指针的惟一方法是显式地使用 & 运算符和,以显式使用成员函数的限定名。如果是你的话 &Foo::Resize .

    但是,这都与要点无关,因为您显然需要一个指向 普通的 函数不是成员函数。指向成员函数的指针是一个性质完全不同的对象,甚至与指向普通函数的指针都不太相似。换句话说,你试图做的是不可能的。无法将指针传递给 Foo::Resize glutReshapeFunc 不管你做什么。

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

        3
  •  2
  •   Loki Astari    14 年前

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

    如果您只有一个foo对象,或者您考虑将方法设为静态,那么就停止。这是一个C库,因此DES不理解C++ ABI。将代码切换回使用C函数的状态。如果您的代码是用C++文件编写的(或者编译为C++),那么您必须声明函数为 外部“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);
    }
    
        4
  •  2
  •   Chris Creel    12 年前

    正如上面RemusRusanu所说,只需在函数中添加static就可以做到这一点。这样可以确保该方法始终可用。