2010-03-08 433 views
15

我试图在类中声明一个回调函数,然后在某处我读取的函数需要是静态的,但它没有解释为什么?为什么回调函数在类中声明时需要是静态的

#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); 
} 

回答

20

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

静态函数几乎就像一个全局函数:它不需要调用一个类实例。所以你只需要获得指向该函数的指针就可以调用它。

看看std :: function(或者std :: tr1 :: function或者boost :: function,如果你的编译器还没有提供的话),它对你的情况很有用,因为它允许你使用任何是可调用的(提供()语法或运算符)作为回调,包括可调用对象和成员函数(请参阅本例的std :: bind或boost :: bind)。

8

回调需要是静态的,因此它们没有隐含的this参数作为其函数签名中的第一个参数。

0

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

2

它需要是静态的,以便函数签名匹配。当调用成员函数时,调用中会包含一个隐藏参数(即“this”指针)。在静态成员函数中,这个指针不作为参数传递。

2

Marshal Cline给你完整的答案here 。整个部分包含你需要知道的一切。

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

所以建议使用extern "C"非成员函数。

+1

您的链接已损坏。另外,最好发布实际答案而不是链接。 – 2015-08-21 03:52:06

+0

@BenH感谢您的单挑。改进的答案和固定链接。 – daramarak 2015-08-21 06:57:18

+0

加上一个链接(非常有帮助和易于理解的解释) – 2016-12-29 10:37:21

相关问题