回调函数,讲得很好[转载]

                    版权声明:本文为博主原创文章,未经博主允许不得转载。                        https://blog.csdn.net/qq_29924041/article/details/74857469                    </div>
                                                <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-3019150162.css">
                                    <div id="content_views" class="markdown_views">
                <!-- flowchart 箭头图标 勿删 -->
                <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
                    <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
                </svg>
                                        <p><strong>C++学习:回调函数(callback)</strong></p>

简介:
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应
可能这些概念性的东西不是太好理解,通俗一点,回调函数就是在两个独立函数或者独立类通信的通道

举个例子:

 财务处是负责对公司财务状况和每个月的开销进行汇总
老板只会去看每个月的报表

 那么在这个当中,老板不会去关心,财务整个汇总的过程,他只会去关心结果,那么,如果从面向对象的方法去理解的话,老板是一个对象.财务部是一个对象,当老板想看报表的时候,会跟财务打个招呼,等财务部汇总完了.然后将报表再去提交给老板,那么问题来了,而两个类之间实现通信的就是接口回调,从财务类的中,将结果回调到对象中.这种实现是通过接口自动完成的
 
 如果用C语言的面向过程去理解的话,那么老板想看报表可以理解为一个函数,而财务处计算过程可以看成一个函数,如果老板想看报表的话,可以直接通过调用财务处函数的返回结果来查看.这中主要是依赖于函数指针的形式来实现
 


提示:
博客:章飞_906285288
博客地址:http://blog.csdn.net/qq_29924041


基于C语言的回调函数来实现一个回调的过程

/*
 * ===========================================================================
 *
 *       Filename:  callback.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2017年07月09日 10时27分28秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:   (), 
 *        Company:  
 *
 * ===========================================================================
 */

#include<stdio.h>
#include<stdlib.h>

/* *
 *财务的统计状况函数
 * */
static int finance_result(int *a,int n);

/* *
 *老板想看财务报表
 * */
void boss_read_finance(int *array,int n,int (*fp)(int*,int));

int main(int argc,char* argv[]){
  //定义一个数组数据
  int array[10] = {1,2,3,4,5,6,7,8,9,10};
  //因为C语言中函数名也是地址,因此对于形参数是函数指针的话,这个时候直接将地址传进去就可以了;
  //注意:函数指针是指向函数的地址,对于fp是地址,那么调用的时候固然需要(*fp)
  //也可以这样写:
  //int (*fp)(int *a,int n);
  //fp = finance_result;
  //boss_read_finance(array,10,finance_result);

  boss_read_finance(array,10,finance_result);

  return 0;
}

/* *
 *老板查看财务状况的实现,参数中有一个函数指针,
 * */
void boss_read_finance(int* array,int n,int (*fp)(int* a,int n)){
  //对于老板来说,他是不需要去了解财务部的具体实现的过程,只要结果就行了
  //这就有助于我们对函数封装
  int result = (*fp)(array,n);
  printf("caculate result:%d\n",result);
}

/* **
 *财务计算报表的具体实现
 * */
static int finance_result(int* a,int n){
  int result = 0;
  int i =  0;
  for(i = 0;i < n; i++){
    result += *(a+i);
  }
  return result;
}
 
 
  • 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
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

基于C++面向对象过程的代码

/*
 * ===========================================================================
 *
 *       Filename:  finance.h
 *    Description:  
 *        Version:  1.0
 *        Created:  2017年07月09日 10时52分53秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:   (), 
 *        Company:  
 *
 * ===========================================================================
 */

#ifndef __FINANCE_H__
#define __FINANCE_H__

namespace zzf{

#include<iostream>
using namespace::std;
/* *
 *定义一个callback的接口
 * */
class CallBack{
  public: 
    virtual void setFinanceResult(int result)  const = 0;
};

/* *
 *财务:
 专门用于计算结果的
 * */
class Finance{
  public:
    Finance(CallBack* mCallBack2):mCallBack(mCallBack2){
      cout << "finance constructor" << endl;
    }
    ~Finance(){
      cout << "finance destructor" << endl;
    }
  void caculateFinance(int * a,int n){
    int result = 0;
    for(int i = 0 ;i < n;i++){
      result += *(a + i);
    }
    if(mCallBack != NULL){
      cout <<"result:"<<result<<endl;
       mCallBack->setFinanceResult(result);
    }
  }  



  private:
     CallBack* mCallBack;
};


/* *
 *老板,实现接口callback
 * */
class Boss:public CallBack{
  public:
     Boss(){
       //将接口实例化后,传递给Finance
       mFinace = new Finance(this);
      cout << "boss constructor" << endl;
     }
     ~Boss(){
       delete mFinace;
       cout << "boss destructor" << endl;
     }
     //查看财务的函数
     void readFianace(int *array ,int n){
       cout << "boss readFianace"<< endl;
       mFinace -> caculateFinance(array,n);
     }
    //实现后的回调函数,这个函数就是用来接收回调的值的
     void setFinanceResult(int result) const{
       cout << "caculate result:" << result << endl;
     }
  private:
     Finance *mFinace;
};


}
#endif
 
 
  • 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
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
/*
 * ===========================================================================
 *
 *       Filename:  testFinance.cpp
 *    Description:  
 *        Version:  1.0
 *        Created:  2017年07月09日 11时04分55秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:   (), 
 *        Company:  
 *
 * ===========================================================================
 */

#include<iostream>
#include<finance.h>
using namespace::std;
using namespace::zzf;

int main(int argc,char *argv []){

  int array[10] = {1,2,3,4,5,6,7,8,9,10};

  Boss boss;

  boss.readFianace(array,10);

  return 0;
}

 
 
  • 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

其实这个案例能够让我们对回调有更加深刻的认识:
1:老板想查看财务(调用自己函数,函数在boss内)
2:通知财务,我要查看报表(进行计算的过程,函数在finance内部)
3:财务算好之后,返回给老板(回调的函数在boss内部)
也就是回调就是把不需要自己处理的东西放到别的类去,然后等其处理完毕之后,再返回给调用的类.

总结:
回调四步曲:

  1. 定义一个回调接口
  2. 调用类去实现这个接口,重写方法
  3. 被调用者将接口做为参数传递进去,并且在某个时刻进行出发
  4. 调用者在调用的时候去实例化这个回调接口(如上述案例中因为已经实现了接口,所以将类本身对应的对象作为参数传递进去)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值