C++_回调函数的理解

由于最近项目需求,需要学习一些回调函数的知识。对于指针本来掌握就不够熟练的我来说,网上的资料看的也是一头雾水。其实,看文字描述不如看代码描述。下面就介绍一下我所理解的回调函数。
介绍之前,必须提醒读者,不要被“回调”两个字所迷惑,很多人觉得回调函数神秘,就是有了先入为主的观念,被“回调”所欺骗。我们首先来看一段很简单的例子:

int main(int argc,char* argv[])
{
    printf("Hello World!\n");
    return 0;
}

这是文明很熟悉的“Hello World!”,如何使这个程序更高级一些呢?自然有人想到使用函数调用的方法,于是就有了下面这段改进版:

void Invoke(char* s);

int main(int argc,char* argv[])
{
    Invoke("Hello World!\n");
    return 0;
}

void Invoke(char* s)
{
    printf(s);
}

有了函数调用程序确实变得高端了一些,但是回调函数需要我们具备一定的函数指针的技能,如果再升级一下这个程序,会是什么样子呢?

void Invoke(char* s);

int main()
{
    void (*fp)(char* s);    //声明一个函数指针(fp)        
    fp=Invoke;              //将Invoke函数的入口地址赋值给fp
    fp("Hello World!\n");   //函数指针fp实现函数调用
    return 0;
}

void Invoke(char* s)
{
    printf(s);
}

在这个程序中,我们把函数的入口地址给了一个指针,通过调用指针,来间接的调用函数。在此基础上我们来介绍回调函数。如果我们把Invoke函数的地址作为一个参数传递到一个中间函数中,然后在主函数中通过调用这个中间函数来输出这个函数,也可以实现相同的功能。虽然看起来好像绕了很长的一段路,但是这样做总是有它适用的场景,这种场景在下文中会有介绍。下面就是使用回调函数后的程序:

//定义回调函数
void PrintfText() 
{
    printf("Hello World!\n");
}

//定义实现回调函数的"调用函数"
void CallPrintfText(void (*callfuct)())
{
    callfuct();
}

//在main函数中实现函数回调
int main(int argc,char* argv[])
{
    CallPrintfText(PrintfText);
    return 0;
}

很明显,我们能看到两个函数,一个是我们自己写的有一定功能的函数(PrintfText),另一个是中间函数(CallPrintfText),最后我们在主函数需要使用PrintfText的地方,通过调用CallPrintfText来实现函数的调用。
这就是一个最简单最基本的回调函数的例子。在这里并没有体现出回调函数的灵活之处,我们再举一个例子来说明。

/* para_callback.h */  
#ifndef PARA_CALLBACK_H  
#define PARA_CALLBACK_H  

typedef void (*callback_t)(void *);  
extern void repeat_three_times(callback_t, void *);  

#endif  
/* para_callback.c */  
#include "para_callback.h"  

void repeat_three_times(callback_t f, void *para)  
{  
     f(para);  
     f(para);  
     f(para);  
}  
/* main.c */  
#include <stdio.h>  
#include "para_callback.h"  

void say_hello(void *str)  
{  
     printf("Hello %s\n", (const char *)str);  
}  

void count_numbers(void *num)  
{  
     int i;  
     for(i=1; i<=(int)num; i++)  
          printf("%d ", i);  
     putchar('\n');  
}  

int main(void)  
{  
     repeat_three_times(say_hello, "Guys");  
     repeat_three_times(count_numbers, (void *)4);  
     return 0;  
}  

从这个例子可以看到,调用函数不需要知道回调函数具体的功能,只要参数列表对应,就可以调用同一个中间函数,完成不同的功能。
相信,读到这里,你已经对回调函数有了一些认识,我们再把这些认识总结成文字。所以到底什么是回调函数呢?简而言之,回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
举个现实中的例子:你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。
应用程序,回调函数和中间函数的关系如下:
应用程序,回调函数和中间函数的关系

在使用回调函数时,主要有三步:1,声明;2,定义;3,设置触发条件,就是在你的函数中把你的回调函数名称转化为地址作为一个参数,以便于系统调用。回调函数就相当于一个中断处理函数,由系统在符合你设定的条件时自动调用。
所谓回调函数就是按照一定的形式由你定义并编写实现内容,当发生某种事件时,而由系统或其它函数来调用的函数。使用回调函数实际上就是在调用某个函数时,将自己编写的一个函数的地址作为参数传递给那个函数。而那个函数在需要的时候,也就是某种事情发生的时候,利用传递的函数地址调用回调函数,这时你可以利用这个机会在回调函数中处理消息或完成一定的操作。回调函数只能是全局函数,或者是静态函数,因为这个函数只是在这个类中使用,所以为了维护类的完整性,我们用类的静态成员函数来做回调函数。
这就是我所理解的回调函数,希望能够帮助到你。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值