回调函数就是一个通过函数指针调用的函数。如果把一个函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
举例说明:
#include
void print();
int main(void)
{
void (*fuc)();
fuc = print ;
fuc();
}
void print()
{
printf("hello world!\n");
}
我们首先定义了一个函数指针fuc ,这个函数指针的返回值为void型,然后我们给函数指针赋值,赋值为print,也就是print函数的首地址,此时fuc获得了print的地址,fuc的地址等于print的地址,所以最终调用fuc();也就相当于调用了print();
#include
int add_ret() ;
int add(int a , int b , int (*add_value)())
{
return (*add_value)(a,b);
}
int main(void)
{
int sum = add(3,4,add_ret);
printf("sum:%d\n",sum);
return 0 ;
}
int add_ret(int a , int b)
{
return a+b ;
}
我们把函数的指针(地址),这里也就是add_ret,作为参数int add(int a , int b , int (*add_value)()) , 这里的参数就是int(*add_value)() , 这个名字可以随便取,但是要符合C语言的命名规范。当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
用户将add_ret这个函数以参数的形式传入开发者实现的add函数,add函数就会返回一个数字给用户,开发者没必要告诉用户他实现了什么东西,用户也并不知道开发者是怎么实现的,用户只需要传入自己写的函数,便可以得到开发者实现的函数的返回值,开发者可以将内容封装起来,将头文件以及库文件提供给用户。
接下来看一下类的成员函数作为回调函数:
在c++中,一般需要使用类进行函数的封装。但是在调用一般的类的成员函数时,使用类的成员调用时,需要传递this指针
《深入探索C++对象模型》中提到成员函数时,当成员函数不是静态的,虚函数,那么我们有以下结论:
(1) &类名::函数名 获取的是成员函数的实际地址;
(2) 对于函数x来讲obj.x()编译器转化后表现为x(&obj),&obj作为this指针传入;
(3) 无法通过强制类型转换在类成员函数指针与其外形几乎一样的普通函数指针之间进行有效的转换。
所以,要在回调函数中传入一个类的普通成员函数时,this指针无处安放,使得回调函数比较复杂。
#include
#include
using namespace std;
using namespace std::placeholders;
typedef std::function Fun;
class B{
public:
void call(int a,Fun f)
{
f(a,2);
}
};
class Test{
public:
void callback(int a,int b)
{
cout<
http://blog.csdn.net/mangobar/article/details/41828893
https://www.cnblogs.com/lidabo/p/3597559.html(成员函数 函数指针)
https://www.cnblogs.com/lidabo/p/6639363.html
https://blog.csdn.net/hyp1977/article/details/51784520