zoukankan      html  css  js  c++  java
  • 回调函数的理解

    先看两个例子,比较不同:

    例一(有回调函数)

    #include <iostream>
    using namespace std;
    void foo_one()
    {
        cout<<"foo_one"<<endl;
    }
    void foo_two()
    {
        cout<<"foo_two"<<endl;
    }
    typedef  void(*FUNC)();
    
    void manage(FUNC f)
    {
        cout<<"函数开始"<<endl;
        f();
        cout<<"函数结束"<<endl;
    }
    int main()
    {
        manage(foo_one);
        manage(foo_two);
        return 0;
    }

    例二(没有回调函数)

    #include <iostream>
    using namespace std;
    void foo_one()
    {
        cout<<"foo_one"<<endl;
    }
    void foo_two()
    {
        cout<<"foo_two"<<endl;
    }
    void manage()
    {
        cout<<"函数开始"<<endl;
        foo_one();
        cout<<"函数结束"<<endl;
    }
    int main()
    {
        manage();
    
        return 0;
    }

    如果想要在manage函数中调用foo_two,只能对manage函数进行改写:

    #include <iostream>
    using namespace std;
    void foo_one()
    {
        cout<<"foo_one"<<endl;
    }
    void foo_two()
    {
        cout<<"foo_two"<<endl;
    }
    void manage()
    {
        cout<<"函数开始"<<endl;
        foo_two();
        cout<<"函数结束"<<endl;
    }
    int main()
    {
        manage();
    
        return 0;
    }

    如果manage函数提供给你了不准你改动源代码怎么办?(实际情况也是,不可能让你随随便便改动源码),因此回调函数的价值就来了,对比例1发现,只要像manage传入不同的函数指针即可,不但灵活性增加了,而且也满足了不随随便便提供源码修改的原则.

    用网上的一个例子总结一下:

    有一家旅馆提供叫醒服务,但是要求旅客自己决定叫醒的方法。可以是打客房电话,也可以是派服务员去敲门,睡得死怕耽误事的,还可以要求往自己头上浇盆水。这里,“叫醒”这个行为是旅馆提供的,相当于库函数,但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数。而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数。
     
    代码模拟该例子:
    #include <iostream>
    using namespace std;
    void handle_one()
    {
        cout<<"请打电话叫醒我"<<endl;
    }
    void handle_two()
    {
        cout<<"请叫服务员叫醒我"<<endl;
    }
    void handle_three()
    {
        cout<<"我睡的比较死,请叫服务员往我头上浇一盆水叫醒我"<<endl;
    }
    
    typedef  void(*FUNC)();
    void manage(FUNC f)
    {
        f();
    }
    int main()
    {
        FUNC arr[3]={handle_one,handle_two,handle_three};
        int x;
        cout<<"我是旅店老板,请选择叫醒你的方式:"<<endl;
        cin>>x;
        switch (x)
        {
        case 0:
        manage(arr[0]);
        break;
        case 1:
        manage(arr[1]);
        break;
        case 2:
        manage(arr[2]);
        break;
        }
        cout<<"好的,我知道了"<<endl;
    
        return 0;
    }

    输出示例:

     
     
  • 相关阅读:
    vue-cli构建的项目手动添加eslint配置
    给通过canvas生成的二维码添加logo
    webpack打包时候去掉console.log配置
    gist.github.com 被墙无法访问解决办法
    axios.js 在测试机ios7.1的iphone4中不能发送http请求解决方案
    linux 系统的7个运行级别
    今天遇到了不能创建mysql函数
    今天测试大商创,遇到了 upstream sent too big header while reading response header from upstream
    mysql5.7 datetime 默认值为‘0000-00-00 00:00:00'值无法创建问题解决
    IE浏览器中判断IE版本
  • 原文地址:https://www.cnblogs.com/SunShine-gzw/p/13766924.html
Copyright © 2011-2022 走看看