C++:指向另一个类函数的函数指针

3
我有两个类。
class B {
public:
    int func(int i);
};

class A {
public:
    typedef int (B::*fPtr)(int);
    void run();
    B* mB;
};

void A::run() {
    // create a pointer
    fPtr p = &(B::func);
    // invoke the function
    mB->*p(2);     <------- Compilation Error
}

我需要在A的运行函数中创建一个指向func()的指针。我得到了编译错误,提示mB没有对应一个带有1个参数的函数。
请帮忙解决。

你为什么要把这个问题搞得这么复杂?你为什么要打继承的标签,而实际上你并没有使用它呢?你听说过接口吗? - Ed Heal
1
为什么不使用 std::function/boost::function?它们往往比愚蠢的 C 风格函数指针更灵活、更简单。 - user406009
1
@EthanSteinberg 成员函数指针与 C 函数指针几乎没有关系,不能存储在 std/boost::function 中。 - Benjamin Lindley
@BenjaminLindley 在 std::function 中存储成员函数非常简单。在这种情况下,示例将是 std::function<int(B*,int)> fun = &B::func。然后调用将会更加简单明了,即 fun(mB,2); - user406009
3个回答

6
您需要在函数表达式周围加上括号:
(mB->*p)(2);

但是如其他人所指出的,你尝试做的事情肯定有更好的方法。


首先,感谢您的帮助。至于使用上面提到的其他东西,我认为这个解决方案在我的情况下是最合适的。 - Alex Kul

2

类的实例方法总是有一个隐藏的第一个参数,指向this指针,因此它与您的函数指针typedef不兼容。 直接获取成员函数的指针是不可能的。 典型的解决方法是使用“thunk”,您可以传递一个静态函数,该函数接受一个通用的“catch all”参数(例如void *),该参数可以在静态转换为您选择的指针上调用成员函数。 示例:

class B
{
public:
    static void MyThunk(void * obj)
    {
        static_cast<B *>(obj)->MyRealFunc();
    }

    void MyRealFunc()
    {
        // do something here
    }

    // . . .
};

您可以轻松地获取静态函数的指针,因为它没有“隐藏的this”,只需使用B::MyThunk引用它即可。如果您的函数需要额外的参数,则可以使用类似于函数对象的东西来捕获必要的参数和状态。
您应该绝对阅读这个C++ FAQ Lite页面,它告诉您更多关于所有这些的信息:成员函数指针

好的回答。为什么obj的类型必须是void *?我更喜欢B * - David Grayson
@bobbymcr:我猜你以前从未使用过 ->*.* 运算符?它们确实允许通过指针调用对象实例上的方法,就像 Alex 的示例所展示的那样。他只是缺少一组括号来使他的代码正确编译。 - Remy Lebeau
1
通常情况下,您必须使用一些“裸指针”类型来与Win32上的诸如CreateThread之类的东西进行交互,该函数只允许您将LPVOID传递给您的ThreadStart函数指针。当然,您应该尽可能地使事情强类型化,但并不总是有选择的余地。 - bobbymcr

1
为什么不能调用 mB->func(2);
如果您需要不同的 B 函数,可以考虑使用 virtual 函数和类继承。

考虑到我的项目设计和我想要实现的目标,这就是我要采取的解决方案。 - Alex Kul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接