【问题标题】:Polymorphism: "A pointer to a bound function may only be used to call the function"多态性:“指向绑定函数的指针只能用于调用函数”
【发布时间】:2013-09-06 07:31:21
【问题描述】:

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

在 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);
    ...
}

它仍然给我一个错误(一个不同的)。 有什么办法解决这个问题?

【问题讨论】:

    标签: c++ opengl pointers glut


    【解决方案1】:

    它不会这样工作,因为SizeMod 是一个非静态类成员方法,所以它需要this 才能被调用。您必须将SizeMod 设为静态。

    【讨论】:

    • 这导致我出现链接错误。错误 LNK2019:函数 _main 中引用的未解析外部符号“public:static void __cdecl graphics::SizeMod(int,int)”(?SizeMod@graphics@@SAXHH@Z)
    • 在 cpp 文件中的void SizeMod(int w, int h) 行中的SizeMod 之前添加一个graphics::
    • @MM。使用静态成员函数不能保证有效,因为 C++ 静态成员函数和 C 函数之间的调用约定可能不同。
    • @Annonymousisnobody:请参阅我的答案,了解使用 C++11 lambda 的不错解决方案。它还解释了为什么这些东西不能“混合”。
    • @datenwolf:你不能对静态方法强制执行所需的约定吗?我想你可以。
    【解决方案2】:

    GLUT 是一个 C API。 glutReshapeFunction 期望对签名函数的回调

    void (int, int)
    

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

    graphics::void(int, int)
    

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

    void(graphics*, int, int)
    

    如果透过 C ABI 的眼镜看。

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

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

    • 类型不匹配
    • 并且无法以某种方式传递实例

    编辑:正如 Mike Dinsdale 所指出的,C++ lambda 在这里不起作用。


    说真的,我真的厌倦了一次又一次地回答同一个问题,一次又一次,一次又一次……每周大约被问 3 次。

    【讨论】:

    • 您的 lambda 代码似乎存在一些问题:graphics gr() 是 MVP,您没有在 lambda 中捕获 gr,最严重的是,我不认为 lambda 具有捕获功能可以转换成函数指针(参见例如here
    • @MikeDinsdale:看来你是对的。哦,好吧,然后回到我在另一个与 C++ 成员函数和回调有关的答案中建议的 ffcall hack:stackoverflow.com/a/8375672/524368
    猜你喜欢
    • 2012-03-09
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    相关资源
    最近更新 更多