zoukankan      html  css  js  c++  java
  • 使用tr1的bind函数模板

    最近把公司的VS2008统一升级为SP1了,虽然还是有些跟不上时代,毕竟C++17标准都出了,但是,对于成熟的商业软件开发而言,追求更新的C++标准肯定不是正道。升级SP1的VS2008可以支持TR1的C++标准了,算是跟上了部分C++11的脚步。本文将说说TR1中新functional头文件中function和bind模板的使用.

    就我个人理解的这个新标准来看,借由这两个模板,我们将能更灵活的使用函数指针,比如函数指针的调用和使用回调机制等。通过使用占位符,我们将可以使用成员函数来进行回调,不得不说,这让我们的编程方式得以更加现代化。

    如代码所示:

    #include <functional>
    typedef std::tr1::function<void (int)>  Functor;
    

      

    如上,通过std::tr1::function 我们定义了Functor的函数类型,该类函数的返回值为void ,参数为int类型,

    void showNum(int param)
    {
    std::cout << "param is : "<<param <<std::endl; 
    }
    
    void testSimpleFunctional()
    {
    Functor namedFunc = Functor(&showNum);
    Functor namedFunc2 = bind(&showNum,std::tr1::placeholders::_1);
    namedFunc(22);
    namedFunc2(33);
    }
    

      

    返回的结果如你所料:

    param is : 22
    param is : 33
    

      

    首先,我们定义了一个void int类型的函数showNum,然后将函数以模板HandlerEvent赋值给namedFunc,然后调用namedFunc,而namedFunc2 则使用bind模板,将showNum绑定到namedFunc2上,使用占位符std::tr1::placeholders::_1来表明其参数,其最后的效果 和直接调用showNum都是一样的。那么,你可能会问,我还不如直接调用showNum来的爽快,是的,在这种情况下,确实如此。

    那么,使用std::tr1::function的场景在哪里呢,答案之一是事件回调,答案之二是委托;

    事件回调

    回调算是老生常谈了,在异步非阻塞的事件驱动的编程模型中,回调机制属于一等公民,像Nodejs这样的平台,回调已经内嵌为基本实现了,这里不展开说明了。为了实现回调,以前,我们经常使用的就是函数指针。现在,让我们使用bind来实现下:

    Show Me The Code

    class CallBackCls
    {
    public:
    void setCallback(const Functor& callBackFunc){
    m_callBackFunc = callBackFunc;
    }
    
    private:
    Functor m_callBackFunc;
    public:
    void run(int param){
    //below to do the opetration
    std::cout << "callcls handle it done and call" << std::endl;
    //operation done and notify the callee
    if(m_callBackFunc){
    m_callBackFunc(param);
    }
    }
    };
    
    class MainCls
    {
    public:
    MainCls(int x):m_x(x){
    m_callBackCls.setCallback(std::tr1::bind(&MainCls::onCallBack,this,x));
    }
    void mainRun(){
    m_callBackCls.run(m_x);
    }
    private:
    void onCallBack(int param){
    std::cout << "after callback parm callBackFunc in Main is:"<<param <<std::endl;
    }
    CallBackCls m_callBackCls;
    int m_x;
    };
    

      



    //在Main函数中测试
    MainCls cd = MainCls(555);
    cd.mainRun();
    

      

    结果:

    callcls handle it done and call:
    parm callBackFunc in Main is:555

    分析可知:通过bind将MainCls的成员函数onCallBack以及其参数绑定为回调函数,执行run后,CallBackCls的run函数将在执行完自己的任务后回调MainCls的成员函数onCallBack,通过这种方式,可以很好的达到非阻塞的目的。

    另外,通过类的继承,虚函数等,我们可以向深挖掘更多高级的用法,这里不展开了。

    委托

    委托(delegate)在C#里风生水起,而在C++里却是相对沉寂,因为C++没有,只有类似的委托。可参考长文

    面向对象的函数指针也被称为闭包(closures) 或委托(delegates), 在类似的语言中已经体现出了它的价值. 在 Delphi(Object Pascal) 中, 他们是 VCL (Borland's Visual Component Library, 宝蓝可视化组件) 的基础. 最近的 C# 让委托的概念更为流行, 这也成为 C# 成功的因素之一. 在许多程序中, 委托可以简化由松耦合对象组成的高级设计模式(观察者模式, 策略模式, 状态模式)的使用. 毫无疑问, 委托在 C++ 中也是非常有用的.

    理论上说,委托应该算是回调的一种,即 委托机制的本质就是调用成员函数的函数指针,实现回调。事实上,本文开篇的例子已经算是委托的一种了,但是没有涉及到具体的类,显示有些多余,而一旦使用了类的成员函数,我们就将对象的状态以及类的成员变量都汇集在一起,函数指针的可用性被大大增强了。例子有机会再补充吧。

  • 相关阅读:
    20155201 第十二周课堂实践
    20155201 实验三《Java面向对象程序设计》实验报告
    20155201 第十一周Java课堂实践
    20155201 2016-2017-2 《Java程序设计》第十周学习总结
    20155201 2016-2017-2 《Java程序设计》第九周学习总结
    20155201 实验二《Java面向对象程序设计》实验报告
    Keras官方中文文档:Keras安装和配置指南(Windows)
    Keras官方中文文档:Keras安装和配置指南(Linux)
    Keras官方中文文档:常见问题与解答
    TensorLayer官方中文文档1.7.4:API – 数据预处理
  • 原文地址:https://www.cnblogs.com/Stultz-Lee/p/9992180.html
Copyright © 2011-2022 走看看