你会使用回调函数吗?

简介:

之所以以反问的形式提出这个问题,是因为以我的观点来看,“回调函数”对一个C/C++程序员来说是很平常的,一些API的使用,一些接口的设计均要用到回调函数的概念。但是我面试过的一些有“多年工作经验”的C系程序员,共事过的一些“有经验”的同事竟然对回调函数不了解,更别提使用了。那今天我就以我的理解来梳理一下回调函数的概念和使用场景。

什么是回调函数?

维基百科释义:

在计算机程序设计中,回调函数,或简称回调(Callback),是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。

不好理解吧?那举个生活中常见的例子:你在网上买了东西通过快递来配送,给你两个选择:
1. 你可以一遍遍的打快递配送公司的电话,查询你的货是否到了,是否可以领取;
2. 你可以安心的干自己的事,等配送人员把货送到你家门口打电话通知你,你去领取;
你会选择哪种方式处理?当然你会选择第二钟处理方式,好处不言而喻,这也正是回调函数的形象解释。

回调函数的实现原理

对于C/C++语言来说就是将函数指针作为参数传递给其它函数。

回调函数实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using  namespace  std;
void  Sum( int  a,  int  b)
{
     int  c = a + b;
     cout <<  "Sum = "  << c << endl;
}
typedef  void  (*FuncCallBack)( int int );
void  GetCallBack( const  int  i, FuncCallBack cb)
{
     if  (1 == i)
     {
         cb(3, 4);
     }
}
void  main()
{
     GetCallBack(1, Sum);
     system ( "pause" );
}

运行结果:Sum = 7  ,对于上面这个例子FuncCallBack就是回调函数的定义,Sum是其实现


另外,在C++的接口设计里常常会遇到这种情况:需要向类接口中注册很多不同的回调函数,这样这些回调函数的定义和管理便比较杂乱,这样我们可以借用delegate类的概念来这么实现回调。

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
using  namespace  std;
class  IEvent
{
public :
     virtual  void  Test1( int  i) = 0;
     virtual  void  Test2( int  i) = 0;
     virtual  void  Test3( int  i) = 0;
};
class  TestEvent: public  IEvent
{
public :
     void  Test1( int  i) { cout <<  "Test1 : "  << i << endl;}
     void  Test2( int  i) { cout <<  "Test2 : "  << i << endl;}
     void  Test3( int  i) { cout <<  "Test3 : "  << i << endl;}
private :
     int  p;
};
class  NotifyEvent
{
public :
     void  Run( int  flag)
     {
         switch (flag)
         {
         case  1:
             testEvent_->Test1(1);
             break ;
         case  2:
             testEvent_->Test2(2);
             break ;
         case  3:
             testEvent_->Test3(3);
             break ;
         default :
             break ;
         }
     }
     void  SetMyEvent(IEvent* testEvent) {testEvent_ = testEvent;}
private :
     IEvent* testEvent_;
};
int  _tmain( int  argc, _TCHAR* argv[])
{
     IEvent* ptr_event =  new  TestEvent;
     NotifyEvent notifyEvent;
     notifyEvent.SetMyEvent(ptr_event);
     notifyEvent.Run(1);
     notifyEvent.Run(3);
     system ( "pause" );
     return  0;
}

运行结果:Test1 : 1    Test3 : 3

对于接口使用者而言,暴露出了IEvent这个接口,回调的管理都在这个接口中,避免了上述管理杂乱的情况。

本文转自永远的朋友博客51CTO博客,原文链接http://blog.51cto.com/yaocoder/1221422如需转载请自行联系原作者


yaocoder

相关文章
|
28天前
回调函数
【8月更文挑战第21天】
11 1
|
4月前
|
人工智能 机器人 中间件
【C++】C++回调函数基本用法(详细讲解)
【C++】C++回调函数基本用法(详细讲解)
|
10月前
|
前端开发 JavaScript 测试技术
理解回调函数
理解回调函数
70 0
|
11月前
【回调函数】
【回调函数】
37 0
|
11月前
|
API C++
回顾C++回调函数
回顾C++回调函数
「C/C++」C/C++ 回调函数
「C/C++」C/C++ 回调函数
115 0
|
Java C语言 C++
c++ 回调函数的使用
java的回调函数可能都不陌生,使用接口interface的方式,在接口中定义回调函数。函数参数可以是interfance。调用函数的时候,实现这个interface的函数即可。
185 0
c++ 回调函数的使用
回调函数是异步吗?回调函数和异步操作的关系
回调函数是异步吗?回调函数和异步操作的关系