• 几种回调的对比


    C++中实现回调的几种方式
    在C++中使用回调函数的几种方式(函数指针)
    实现回调机制的几种方式

    一、普通回调函数(通过函数指针)

    在C++中使用回调函数的几种方式
    【本博】C++语法

    1、同步回调

    #include
    
    int Callback_1(int x) // Callback Function 1
    {
        printf("Hello, this is Callback_1: x = %d ", x);
        return 0;
    }
    
    int Callback_2(int x) // Callback Function 2
    {
        printf("Hello, this is Callback_2: x = %d ", x);
        return 0;
    }
    
    int Callback_3(int x) // Callback Function 3
    {
        printf("Hello, this is Callback_3: x = %d ", x);
        return 0;
    }
    
    int Handle(int y, int (*Callback)(int))
    {
        printf("Entering Handle Function. ");
        Callback(y);
        printf("Leaving Handle Function. ");
    }
    
    int main()
    {
        int a = 2;
        int b = 4;
        int c = 6;
        printf("Entering Main Function. ");
        Handle(a, Callback_1);
        Handle(b, Callback_2);
        Handle(c, Callback_3);
        printf("Leaving Main Function. ");
        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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    2、异步回调

    #include 
    #include 
    #include 
    #include 
     
    void func(std::string str)
    {
        if (str.compare("Hello World 1") == 0)
        {
            char pause = getchar(); // 按回车显示
        }
        std::cout << str << std::endl;
    }
     
    void Print(std::function< void(std::string)> Functional)
    {
        auto a = std::async(std::launch::async, Functional, "Hello World 1");
        auto b = std::async(std::launch::async, Functional, "Hello World 2");
        auto c = std::async(std::launch::async, Functional, "Hello World 3");
    }
     
    int main()
    {
        Print(func);
        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

    二、frame中的CCallback回调管理类(通过类指针执行固定的函数onCallback)

    (一)实现原理

    1、管理类中通过map<数据类型,回调类信息>管理回调信息
    2、回调类注册时,将要处理的数据类型,和处理数据的类指针,存入map
    3、回调类实现虚函数onCallback(int type, void* pObj)
    4、发起回调的类,调用管理类的FireCallback(int type, void *pObj),查询map中type对应的回调类指针,通过指针调用其onCallback实现回调。

    (二)特点

    1、回调类之间关系,是通过管理类map来找到回调类指针,而发信号是通过一个有交集的类来找到双方指针进行connect交互(或者用单例模式获取)。
    2、发起回调是调用管理类的固定函数(FireCallback),执行回调是通过管理类调用回调类的固定函数(onCallback)。

    三、node中的回调

    四、network中的回调

    m_spConnector->SetNewConnectionCallback(bind(&CTcpClient::newConnection,this, _1));
    void SetConnectionCallback(const CONNECTION_CALLBACK& cb){m_fnConnectionCallback=cb;}
    m_fnConnectionCallback(shared_from_this());
    
    • 1
    • 2
    • 3

    五、frame中的event

    六、network中的event

    通过一个list保存了函数指针,在run()函数中执行回调

    typedef function<void()> EVENT_FUNC;
    QList<EVENT_FUNC> m_lstFuncs;
    for(int i=0; i<lstFuncs.size();i++)
    {
    	lstFuncs[i]();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    七、Qt中的反射

    Qt实现反射机制
    demo:WorkFlow.7z
    帧体类的创建也是应用了反射机制,先是用id注册不同的类型的构造函数,而后根据id调用构造函数创建不同的类(CreateObject)。本质上同通知模式、回调函数类似。

    class ObjectFactory
    {
    public:
      template<typename T>
      static void registerClass()
      {
        constructors().insert(T::staticMetaObject.className(), &constructorHelper<T>);
      }
     
      template<typename T>
      static void registerClass(const QString& name)
      {
          constructors().insert(name, &constructorHelper<T>);
          qDebug() << name <<  constructors().size();
      }
     
      static QObject* createObject( const QString& className, QObject* parent = NULL )
      {
        Constructor constructor = constructors().value( className );
        if ( constructor == NULL )
          return NULL;
        return (*constructor)( parent );
      }
     
    private:
      typedef QObject* (*Constructor)( QObject* parent );
     
      template<typename T>
      static QObject* constructorHelper( QObject* parent )
      {
        return new T( parent );
      }
     
      static QHash<QString, Constructor>& constructors()
      {
        static QHash<QString, Constructor> instance;
        return instance;
      }
    };
    
    • 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

    注册:

    #define REGISTER_OBJECT(className, name) \
    ObjectFactory::registerClass<className>(name); 
     
    void RegisterObject::initialize()
    {
        REGISTER_OBJECT(SteponeNode, "STEP_ONE")
        REGISTER_OBJECT(StepTowNode, "STEP_TOW")
        REGISTER_OBJECT(StepThreeNode, "STEP_THREE")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    创建:

    QObject *AbstractNodeFactory::create(const QString &name)
    {
       QObject *obj = ObjectFactory::createObject(name);
       return  obj;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    【代码随想录】刷题Day39
    WPF 控件专题 UniformGrid 控件详解
    maven+Junit+jacoco的样例demo
    国标视频平台搭建(五)设备接入
    【AutoSAR CAN】01 - CAN 标识符(CanID)长度配置
    最长公共子序列+最长公共子串+编辑距离
    【尚硅谷React】——React全家桶笔记
    餐饮外卖配送小程序商城的作用是什么?
    C#WPF控件Textbox绑定浮点型数据限制小数位方法
    [大家的项目]【编译时 ORM rbatis V4.0 现已发布!第1篇】
  • 原文地址:https://blog.csdn.net/pzs0221/article/details/126446968