回调函数浅析

回调函数

一、回调函数是什么?what?

写在前面:
大神的理解:A "callback" is any function that is called by another function which takes the first function as a parameter。

回调函数被调用时传递了这个函数的指针。

回调的过程有三个函数。F1函数调用了F2函数,F2函数是调用了F3函数的函数。

函数F1调用函数F2的时候,函数F1向函数F2传入函数F3的指针。函数F2执行时,F3调用了函数F3,这个过程就是回调。所以函数F3就称为回调函数。

对于回调函数来说,它的指针传入由F1来完成,在F2执行的时候,被调用。

二、为什么用回调函数?why?

在这里插入图片描述

先说一下回调函数的好处:

如上图所示。根据理论,main program为函数F1,Library function 为函数F2,Callback function为函数F3

这种方式可以将调用分为两层,实际的使用的回调函数的定义是在一层的。F2可以被单独分层,定义好以后可以被封装成lib库,提供接口以后,定义F3,在F1中给F2传入参数,同时传入F3的指针。调用F2即可。完成了解耦,方便不同层的调用。

基本上回调函数的作用就是用来两个线程之间的信息的传递。这就是一种信息传递的方式。传入的内容变成了函数的指针。

图中的例子可以用代码诠释如下:

#include<sting>
#include<iostream>
#include<softwareLib.h> // 包含Library Function所在读得Software library库的头文件

int Callback() // Callback Function//F3
{
    // TODO
    return 0;
}
int main() // Main program//F1
{
    // TODO
    Library(Callback);//F2
    // TODO
    return 0;
}

三、回调函数怎么用?how?

1、不加参数的回调函数

#include<string>
#include<iostream>

using namespace std;

int Callback_1() // Callback Function 1//F3
{
    cout<<"Hello, this is Callback_1."<<endl;
    return 0;
}

int Callback_2() // Callback Function 2//F3
{
   	cout<<"Hello, this is Callback_2."<<endl;
    return 0;
}

int Callback_3() // Callback Function 3//F3
{
   	cout<<"Hello, this is Callback_3."<<endl;
    return 0;
}

int Handle(int (*Callback)())//F2
{
   	cout<<"Entering Handle Function."<<endl;
    Callback();
  	cout<<"Leaving Handle Function."<<endl;
}

int main()//F1
{
    cout<<"Entering Main Function."<<endl;
    Handle(Callback_1);
    Handle(Callback_2);
    Handle(Callback_3);
    cout<<"Leaving Main Function."<<endl;
    return 0;
}

运行结果如下:

Entering Main Function.
Entering Handle Function.
Hello, this is Callback_1.
Leaving Handle Function.
Entering Handle Function.
Hello, this is Callback_2.
Leaving Handle Function.
Entering Handle Function.
Hello, this is Callback_3.
Leaving Handle Function.
Leaving Main Function.

2、带一个参数的回调函数

#include<string>
#include<iostream>

using namespace std;

int Callback_1(int x) // Callback Function 1//F3
{
  	cout<<"Hello, this is Callback_1: x =  "<< x <<endl;
    return 0;
}

int Callback_2(int x) // Callback Function 2//F3
{
   	cout<<"Hello, this is Callback_2: x =  "<< x <<endl;
    return 0;
}

int Callback_3(int x) // Callback Function 3//F3
{
    cout<<"Hello, this is Callback_3: x =  "<< x <<endl;
    return 0;
}

int Handle(int y, int (*Callback)(int))//F2
{
   	cout<<"Entering Handle Function."<<endl;
    Callback(y);
    cout<<"Leaving Handle Function."<<endl;
}

int main()//F1
{
    int a = 2;
    int b = 4;
    int c = 6;
    cout<<"Entering Main Function."<<endl;
    Handle(a, Callback_1);
    Handle(b, Callback_2);
    Handle(c, Callback_3);
    cout<<"Leaving Main Function."<<endl;
    return 0;
}

运行结果如下:

Entering Main Function.
Entering Handle Function.
Hello, this is Callback_1: x =  2
Leaving Handle Function.
Entering Handle Function.
Hello, this is Callback_2: x =  4
Leaving Handle Function.
Entering Handle Function.
Hello, this is Callback_3: x =  6
Leaving Handle Function.
Leaving Main Function.

可以看到在带参数的回调函数中,需要在调用回调函数的函数即F2中传入回调函数的参数和回调函数的指针。

同时,为便于简便,F2函数中的回调函数的指针可以用typedef的方式进行声明。声明的格式如下:

 typedef int (*Callback)(int);

声明以后,可以将Handle函数改成如下所示:

int Handle(int y, Callback cb)
{
   	cout<<"Entering Handle Function."<<endl;
    cb(y);
    cout<<"Leaving Handle Function."<<endl;
}

3、带notify函数的回调函数

在实际的使用过程中,希望能在触发后在使用回调函数,因为回调函数的参数可能不是立即传给它的,存在数据到来的延迟。那么需要有一个函数的作用是接到参数,接到参数以后,通知给调用回调函数的函数,即函数F4

F4F3F1都在同一层。在使用的时候,在F1中调用F2即可。在F1调用的这一层,先声明一个回调函数的指针,对回调函数F3进行实际操作,将F3传入F2,再新建一个传参函数F4,将所有参数塞进提前声明好的回调函数指针里。

为便于理解,可以将带有和不带有notify函数的使用过程进行对比。

不带notify函数的回调函数使用:

#include <string>
#include <iostream>

using namespace std;

typedef  void (*callback)(int);


int register_observer(callback cbk,int i)//注册回调函数并将参数i传递给回调函数//F2
{
  cbk(i);
}

void callback_func(int i)//F3
{
  printf("callback_func received i=%d\n",i);
}

int main()//F1
{
    int i=0;
    register_observer(callback_func,6);

  return 0;
}

运行结果如下:

listen received i=6

notify函数的回调函数的使用:

#include <string>
#include <iostream>

using namespace std;

typedef  void (*callback)(int);//F2层

callback cb;//声明一个callback指针,非常关键的一步//在被封装层实现//F2层

void callback_func(int i)//F3
{
  printf("callback_func received i=%d\n",i);
}

int register_observer(callback cbk)//注册一个回调函数,记录回调函数;//F2层
{
  cb = cbk;
}

void notify_all_observer(int val)//获取传入回调函数测参数,并将参数传递给回调函数指针cb;字面意思是通知F2,获取到参数//F4,和F2同层//把参数记录下来
{
  cb(val);
}

int main()//F1
{
    int i=0;
    register_observer(callback_func);//F2

    int cnt=10;
    while(cnt--)
    {
        cin>>i;
        // cout<<&i<<endl;
        cout<<i<<endl;
        notify_all_observer(i);//F4
    }
  return 0;
}

F1这一层,假如回调函数想传入一个数组,那么可以写成:

typedef  struct{void (*callback)(int);}CALLBACK//结构体
int main()//F1
{
    int i=0;
    CALLBACK cb1;//新建一个结构体
    cb1.callback=callback_func;//将回调函数赋值给回调函数的数组
    register_observer(cb1);//F2//传入回调函数的数组

    int cnt=10;
    while(cnt--)
    {
        cin>>i;
        // cout<<&i<<endl;
        cout<<i<<endl;
        notify_all_observer(i);//F4
    }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值