• 利用function和bind实现回调功能


    介绍一种利用function和bind来实现回调的功能。

    C++参考手册中对function的介绍:

    std::function的实例能存储、复制及调用任何可调用的目标,包括:函数、lambda表达式、bind表达式或其他函数对象以及指向成员函数指针和指向数据成员指针,std::function包含在functional头文件中

    我的理解是当你定义一个function对象时,你是为了用这个对象来存储一个函数指针,在你赋值时,函数本身并不会被调用,直到你需要时,通过调用这个function对象来实现对函数的回调。

    std::bind原型为:

    template< class F, class... Args >
    /*unspecified*/ bind( F&& f, Args&&... args );
    其主要功能是将函数对象与参数绑定并返回一个绑定后的函数对象,第一个参数f指定一个函数对象,args是不定长参数,用于将指定参数传入f对象中。其中对于无法确定的参数,需要在后续调用中设定的可以用占位符指定,std::bind包含在functional头文件中。
    简单的使用说明:
    void f(int n1, int n2, int n3)
    {
       std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << '\n';
    }
    int main()
    {
    //生成函数对象,其中只给n1赋值,n2和n3用占位符表示。
      auto fun=std::bind(f,1,std::placeholders::_2,std::placeholders::_3);
      //bind已给n1赋值,所以这里调用在赋值100是无效的,输出为:1 4 5。
      fun(100,4,5);
    }
    下面说明如何使用function实现回调。

    (1)定义回调函数类型

    typedef std::function<void(int,const char *)>MessageFun;  //无返回值,有一个int型参数和一个const char *型参数

    (2)定义函数对象

    class ThreadObject

    {

    public:

      ThreadObject()

      {

        m_MessageEvent=NULL;

      }

      void setMessageEvent(MessageFun event)

      {

        m_MessageEvent=event;

      }

    private:

      MessageFun m_MessageEvent;

      void run();

    }

    (3)调用函数对象

    void ThreadObject::run()

    {

      //执行任务

          ...

      //执行完毕调用函数对象通知

          if(m_MessageEvent)

        m_MessageEvent(1,"Ok");

    }

    (4)在主线程中定义回调函数处理函数

    class MainObject

    {

    public:

      MainObject();

    private:

      ThreadObject m_thread;

      void onMessageEvent(int status,const char *msg);

    }

    (5)实现回调函数处理

    void MainObject::onMessageEvent(int status,const char *msg)

    {

      if(status==1)

        cout<<msg;

    }

    (6)设置回调函数

    MainObject::MainObject()

    {

      m_thread.setMessageEvent(std::bind(&MainObject::onMessageEvent,this,std::placeholders::_1,std::placeholders::_2));

    }

  • 相关阅读:
    Python 直接赋值、浅拷贝和深度拷贝解析
    Python __name__属性
    Java 中动态 JSON 对象的使用
    Java Spring 中使用 @Valid 进行参数校验
    NAT 网络地址转换(2016)
    深入理解 iptables 和 netfilter 架构
    RFC 1180:朴素 TCP/IP 教程(1991)
    云计算时代携程的网络架构变迁(2019)
    编程语言中的 6 种内存模型(2016)
    如何基于 Cilium 和 eBPF 打造可感知微服务的 Linux(2019)
  • 原文地址:https://www.cnblogs.com/WushiShengFei/p/9233470.html
Copyright © 2020-2023  润新知