关于C ++:为什么在类中声明回调函数时必须为静态

Why callback functions needs to be static when declared in class

我试图在类中声明一个回调函数,然后在某个地方我读到该函数必须是静态的,但没有解释为什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using std::cout;
using std::endl;

class Test
{
public:
    Test() {}

    void my_func(void (*f)())
    {
        cout <<"In My Function" << endl;
        f(); //Invoke callback function
    }

    static void callback_func()
    {cout <<"In Callback function" << endl;}
};

int main()
{
    Test Obj;
    Obj.my_func(Obj.callback_func);
}

成员函数是需要调用类实例的函数。
如果不提供要调用的实例,则不能调用成员函数。这使得有时更难使用。

静态函数几乎就像全局函数:不需要调用类实例。因此,您只需获取指向该函数的指针就可以对其进行调用。

看一下std :: function(如果编译器尚未提供,则为std :: tr1 :: function或boost :: function),它对您很有用,因为它允许您使用任何可调用的东西(提供()语法或运算符)作为回调,包括可调用对象和成员函数(在这种情况下,请参阅std :: bind或boost :: bind)。


回调必须是静态的,以便它们没有隐式的this参数作为其函数签名中的第一个参数。


非静态方法需要一个'this'实例,并且只能在对象实例上调用。

但是,可以使用非静态回调,但是从语法上讲,它们很难编写。有关说明,请参见http://www.newty.de/fpt/callback.html#member。


克莱恩元帅在这里为您提供完整的答案
。整个部分包含您需要了解的所有内容。

总而言之,它可以解释您需要静态成员,因为不需要this指针(与普通成员方法不同)。但是它还涵盖了使用静态方法可能不足以对所有编译器都适用,因为C和C ++之间的C ++调用约定可能有所不同。

因此,建议使用extern"C"非成员函数。


它必须是静态的,以便功能签名匹配。调用成员函数时,调用中将包含一个隐藏参数(即" this"指针)。在静态成员函数中,this指针不作为参数传递。


如果使用函数指针,则运行时环境在调用函数时无法将引用传递给实例。但是您可以使用std :: mem_fun <>来使用函子和成员方法。