Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说编程|理解回调函数是caller和callee之外的第三者(callbackee),希望能够帮助你!!!。
我们知道,函数是一个功能模块的封装,是算法的具体实现,是高级编程语言中最重要的概念之一。
函数需要被调用才可以发挥作用,不然只是个摆设。
调用时,自然就有了两个主体:
调用函数(caller)→ 被调函数(callee)。
我们知道,函数的参数是函数调用时,被调用函数与调用函数之间重要的沟通渠道,函数的适当设置,可以让被调用函数更灵活,通性性更强,被重用的机会越大。
假设要编写一个排序函数,你可能会编写一个降序函数,也可能编写一个升序函数。而两个函数仅有一行代码的区别,且C、C++是不允许内嵌函数定义的。如果将两个函数整合到一起呢?函数指针做函数参数便闪亮登场了。
函数指针做callee函数的参数,在callee函数中使用这个函数指针变量,而不是将升序或降序的逻辑写死在callee的函数体内。由这个函数指针变量再去调另一个函数(也就是所说的第三者)定义的升序或降序逻辑。这样的由被调函数callee再去调用一个第三者函数(回调函数,可以新建一个英文词callbakcee,)的过程称为回调(callback)。
这样就有了两个调用过程,三个主体:
caller call callee callback callbackee
都有一个调字,在英文中就是call。
// 7-16 通用的冒泡排序函数的应用
#include <iostream>
#include <cstring>
using namespace std;
template <class T>
void sort(T a[], int size, bool (*f)(T,T)); // callee
bool increaseInt(int x, int y) {return x<y;} // callbackee1
bool decreaseInt(int x, int y) {return y<x;} // callbackee2
bool increaseString(char *x, char *y) {return strcmp(x,y)<0;} // callbackee3
bool decreaseString(char *x, char *y) {return strcmp(x,y)>0;} // callbackee4
int main() // caller
{
int a[] = {3,1,4,2,5,8,6,7,0,9}, i;
char *b[]= {"aaa","bbb","fff","ttt","hhh","ddd","ggg","www","rrr","vvv"};
sort(a, 10,increaseInt );
for (i = 0; i < 10; ++i) cout << a[i] <<"\t";
cout << endl;
sort(a, 10, decreaseInt);
for ( i = 0; i < 10; ++i) cout << a[i] <<"\t";
cout << endl;
sort(b, 10, increaseString );
for (i = 0; i < 10; ++i) cout << b[i] <<"\t";
cout << endl;
sort(b, 10, decreaseString);
for ( i = 0; i < 10; ++i) cout << b[i] <<"\t";
cout << endl;
while(1);
return 0;
}
// 通用的冒泡排序函数
template <class T>
void sort(T a[], int size, bool (*f)(T,T))
{
bool flag;
int i, j;
for (i = 1; i < size; ++i) {
flag = false;
for (j = 0; j <size - i; ++j) {
if (f(a[j+1], a[j])) {
T tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
flag = true;
}
}
if (!flag) break;
}
}
/*
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0
aaa bbb ddd fff ggg hhh rrr ttt vvv www
www vvv ttt rrr hhh ggg fff ddd bbb aaa
*/
回调函数的使用可以大大提升编程的效率,这使得它在现代编程中被非常多地使用。同时,有一些需求必须要使用回调函数来实现。
C语言的回调函数只能通过函数指针实现,在C++中则可以使用匿名函数(lambda)或仿函数(functor)作为回调函数。
// 7-19 lambda函数作为通用的冒泡排序函数的参数
#include <iostream>
#include <cstring>
using namespace std;
template <class T>
void sort(T a[], int size, bool (*f)(T,T)); // callee
int main() // caller
{
int a[] = {3,1,4,2,5,8,6,7,0,9}, i;
char *b[]= {"aaa","bbb","fff","ttt","hhh","ddd","ggg","www","rrr","vvv"};
sort<int>(a,10,[](int x, int y)->bool {return x<y; });
for (i = 0; i < 10; ++i) cout << a[i] <<"\t";
cout << endl;
sort<int>(a,10,[](int x, int y)->bool {return x>y; });
for ( i = 0; i < 10; ++i) cout << a[i] <<"\t";
cout << endl;
sort<char*>(b,10,[](char *x, char *y)->bool {return strcmp(x,y) < 0; });
for (i = 0; i < 10; ++i) cout << b[i] <<"\t";
cout << endl;
sort<char*>(b,10,[](char *x, char *y)->bool {return strcmp(x,y) > 0; });
for ( i = 0; i < 10; ++i) cout << b[i] <<"\t";
cout << endl;
while(1);
return 0;
}
// 通用的冒泡排序函数
template <class T>
void sort(T a[], int size, bool (*f)(T,T))
{
bool flag;
int i, j;
for (i = 1; i < size; ++i) {
flag = false;
for (j = 0; j <size - i; ++j) {
if (f(a[j+1], a[j])) {
T tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
flag = true;
}
}
if (!flag) break;
}
}
/*
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0
aaa bbb ddd fff ggg hhh rrr ttt vvv www
www vvv ttt rrr hhh ggg fff ddd bbb aaa
*/
ref
C++|辨析函数指针、函数对象、Lambda表达式及后者最优的原因
-End-
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章