Cpp回调函数的方式和作用

指针函数和函数指针

谈到回调函数得先区分好指针函数函数指针。

##指针函数

指针函数:是指带指针的函数,本质是一个函数,函数的返回类型是某一类型的指针。

声明格式:类型标识符 *函数名(参数表)

示例: int *func(x,y)

首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。由于返回的是一个地址,所以类型说明符一般都是int。

函数返回的是一个地址值,经常使用在返回数组的某一元素地址上。

下面是一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
int *get_letter(int num)
{
static int arr[]={'a','b','c','d','e'};
return &arr[num-1];
}
int main()
{
int num;
std::cin >> num;
std::cout << (char) *get_letter(num) << std::endl;

system("pause");
return 0;
}

子函数int *get_letter(int num)返回的是数组某元素的地址。输出的是这个地址里的值。

(char) *get_letter(num) 其中(char)是将*get_letter(num)返回的数组某元素的地址里的值转换成char类型输出。

函数指针

函数指针是指向函数的指针变量,****本质是一个指针变量。

1
2
int (*f_p)(int x);//声明一个函数指针
f_p = func;//将func函数首地址赋值给指针f_P

指向函数的指针包含了函数的地址的入口地址,可以通过它来调用函数。

声明格式:类型说明符 (*函数名)(参数)

其实这里不能称为函数名,应该叫做指针的变量名。这个特殊的指针指向一个返回整型值的函数。

指针的声明必须和它指向函数的声明保持一致。

指针名和指针运算符外面的括号改变了默认的运算符优先级。如果没有圆括号,就变成了一个返回整型指针的函数原型的声明。

1
2
3
4
5
void (*f_p)();//声明一个函数指针,参数列表为控
//把函数的地址赋值给函数指针,可以采用下面两种形式:
f_p = &Function;
f_p = Function;

取地址运算符&不是必需的,因为单单一个函数标识符就标号表示了它的地址.
如果是函数调用,还必须包含一个圆括号括起来的参数表。

可以采用如下两种方式来通过指针调用函数:

1
2
x = (*f_p)();
x = f_p;

下面是一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

void(*f_p)();
void FileFunc(){std::cout << "FileFunc" << std::endl;}
void EditFunc(){std::cout << "EditFunc" << std::endl;}

int main()
{
f_p = FileFunc;
(*f_p)();//第一种调用方式
f_p =EditFunc;
f_p();//第二种调用方式

system("pause");
return 0;
}
1
2
3
FileFunc
EditFunc
请按任意键继续. . .

回调函数

回调函数是通过函数指针调用的函数:把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就称为回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

引用知乎 常溪玲一个形象的示例:

你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件

下面是一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>  

typedef void (*Fun_p)(int);//定义一个函数指针类型
Fun_p p = NULL;//用Fun定义一个变量p,它指向一个返回值为空参数为int的函数

// 向外提供的回调函数注册接口,提供注册登记服务
void registerFun(Fun_p pCallback)
{
p = pCallback;

}
//达成某一条件后,通过名片(函数指针p),传回结果
void trigger(int result)
{
(*p)(result);//将result传入当前函数指针(*p)所指向的函数(callback函数)
}
//回调函数
void callback(int a)
{
std::cout << "callback result = " << a << std::endl;
}

int main(int argc, char* argv[])
{
registerFun(callback);//注册回调函数

int result = 1;
trigger(result);//触发回调函数关联事件

system("pause");
return 0;
}
1
输出:callback result = 1

typedef int (* Fun_p)(void);定义了一个新类型 Fun

Fun_p p = NULL;//用Fun_p定义一个变量p,p的类型是void (*Fun_p)(int)这样一个函数指针类型。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!