zoukankan      html  css  js  c++  java
  • BOOST 信号与槽,获取槽函数返回值,使用占位参数传递信号携带的参数

    test1: 展示了, 1 信号与槽的基本使用,    2 要获取槽函数的返回值时的注意事项

    #if 1
    
    /*
      参考blog   https://www.cnblogs.com/jiayayao/p/6246161.html   
    
    Qt异步的实现实际上是将信号push到一个队列中,然后由统一的线程来处理信号对应的槽函数而已。
    Boost的信号/槽在信号被触发时,槽函数只能是同步执行,没有像Qt那样的异步接口。
    当然也可以根据这个原理自己封装带异步的信号/槽机制,不过那样的话应该需要另外开启线程了。
    
    */
    #include <iostream>
    #include <boost/signals2.hpp>
    #include <boost/bind.hpp>
    
    using namespace std;
    using namespace boost::signals2;
    
    void slots1()
    {
        cout<<"slots111111111 called"<<endl;
    }
    void slots2()
    {
        cout<<"slots222222222 called"<<endl;
    }
    class A
    {
    public:
        static int staticMemberFunc(int param)
        {
            cout<<"A::staticMemberFunc called, param: "<<param<<endl;
            return 11+param;
        }
        int memberFunc(int param)
        {
            cout<<"A::memberFunc called, param: "<<param<<endl;
            return 6+param;
        }
    };
    int main()
    {
        boost::signals2::signal<void()>   sig;
        boost::signals2::signal<int(int)> sig2;
    
        A a;
    
        // --------- sig() test -----------------
        connection c1 = sig.connect(&slots1);
        connection c2 = sig.connect(&slots2);
        cout<<"First call-------------------"<<endl;
        sig();
    
        if (c2.connected())
        {
            c2.disconnect();
        }
        cout<<"Second call-------------------"<<endl;
        sig();
    
    
        // -------- sig2() test ---------------
        connection c3 =sig2.connect(&A::staticMemberFunc);               // 绑定静态成员函数  -----这是 1 处
    
        connection c4 =sig2.connect(boost::bind(&A::memberFunc, &a, _1));// 绑定成员函数
        // bind 使用 ,参考BLOG : https://www.cnblogs.com/benxintuzi/p/4862129.html   
    
        cout << "------test1---------: " << endl; 
        sig2(44);
    
        cout << "------test2---------: " << endl; 
        cout << *sig2(44) << endl; // 只能返回最后被调用的插槽的返回值
        
        //cout << sig2(44) << endl;  编译报错  , 猜测是不是和连接参数是指针 有关系
        //    于是我们来进行test3  
        cout << "------test3 --------: " << endl; 
        boost::signals2::signal<int(int)> sig3;  
        connection c5 =sig3.connect(A::staticMemberFunc);               // 绑定静态成员函数   -----这是 2处
        sig3(55);
        cout << *sig3(55) << endl; // 只能返回最后被调用的插槽的返回值           //              -----这是 3处
    
        // 实测 1 2 处,加不加取地址,都无所谓。 但是3处一定要加*符号。这是要获取槽函数的返回值的注意事项。
    
        return 0;
    }
    
    #endif
    

     makefile:

    .PHONY: DOIT
    
    DOIT:
    	mips-linux-gnu-g++ -I.  my_boost_test.cpp -L./lib  -lboost_thread -lboost_system -o boost_app  -lrt -lpthread
    
    bind 使用 ,参考BLOG : https://www.cnblogs.com/benxintuzi/p/4862129.html   

    test2:   展示了使用占位参数来填写槽函数的优势所在:这样能够传递信号携带的参数。

    
    #include <iostream>
    #include <boost/signals2.hpp>
    #include <boost/bind.hpp>
    #include <boost/function.hpp>
     
    using namespace std;
    using namespace boost;
     
    template <typename signature>
    class Signal{
     
    public:
    	
    	typedef boost::signals2::signal<signature>  defSignal;      //typedef =>信号
       
       typedef typename defSignal::slot_type       defSlot;        //typedef => 槽
     
    public:
    	//连接槽函数
    	boost::signals2::connection connectFun(const defSlot& slot);
     
    	//重载为函数对象
    	void operator()(typename defSignal::template arg<0>::type a0,  typename defSignal::template arg<1>::type a1);
     
    private:
    	defSignal mSignal;
    };
     
    
    //接收信号后响应的函数
    class FunRecv1{
     
    public:
    	void action(int a, int b){
    	  cout << "result add = " << a + b << endl;
    	}
    };
     
    //接收信号后响应的函数
    class FunRecv2{
     
    public:
    	void action(int a, int b){
    	  cout << "result mutil = " << a * b << endl;
    	}
    };
     
    // 定义
    template <typename signature>
    boost::signals2::connection  Signal<signature>::connectFun(const defSlot& slot){
    
    	return mSignal.connect(slot);
    }
     
    template <typename signature>
    void Signal<signature>::operator()(typename defSignal::template arg<0>::type a0,  typename defSignal::template arg<1>::type a1){
    
    	mSignal(a0,a1);
    }
    
    int main(){
        
    	Signal<void(int,int)> mysignal;
    	FunRecv1 obj_fun1;
    	FunRecv2 obj_fun2;
     
    	//boost::function<void(int,int)> myfun = boost::bind(&FunRecv1::action,&obj_fun1,_1,_2);
    	//信号连接槽函数
       #if  0
    	boost::signals2::connection con1 = mysignal.connectFun(boost::bind(&FunRecv1::action, &obj_fun1, 100, 200));
    	boost::signals2::connection con2 = mysignal.connectFun(boost::bind(&FunRecv2::action, &obj_fun2, 11,  22));
    
       // 小结: 
       // 这里的缺陷,这里没有使用占位参数,所以槽函数内(FunRecvX::action成员函数),每次取的实参都是(100、200)和 (11、22)这两组数据。  
    
       #else
                                                                                                    // 使用占位参数
    	boost::signals2::connection con1 = mysignal.connectFun(boost::bind(&FunRecv1::action, &obj_fun1, _1,  _2 ));
    	boost::signals2::connection con2 = mysignal.connectFun(boost::bind(&FunRecv2::action, &obj_fun2, _1,  _2 ));
    
       
       #endif
    
    
    	mysignal(100,200);
     
       cout << "--------111111111-------" << endl;
    	mysignal(80,70);
       cout << "--------222222222-------" << endl;
    
    	con2.disconnect();
    	mysignal(100,200);
    
       cout << "--------33333333-------" << endl;
    	mysignal(80,70);
     
       return 0;
    }
    

    makefile:

    .PHONY: DOIT
    
    DOIT:
    	mips-linux-gnu-g++ -I.  my_boost_test.cpp -L./lib  -lboost_thread -lboost_system -o boost_app  -lrt -lpthread
    

     运行结果:

    当前使用占位参数的场景:

    # 
    # ./boost_app 
    result add = 300
    result mutil = 20000
    --------111111111-------
    result add = 150
    result mutil = 5600
    --------222222222-------
    result add = 300
    --------33333333-------
    result add = 150
    # 

    不使用占位参数时:

    # ./boost_app 
    result add = 300
    result mutil = 242
    --------111111111-------
    result add = 300
    result mutil = 242
    --------222222222-------
    result add = 300
    --------33333333-------
    result add = 300
    # 
    

      

     一下看不懂没关系,代码复制过去,运行一遍,再看看,就消化了。

     PS:

    还可以设置优先级:

     connect的第一个参数是设置槽函数的优先级,数字越大的槽函数的优先级越低,越靠后执行。所有的槽函数都会被执行,只有最后一个槽函数的返回值作为最终的返回值返回给信号。

    .

    /************* 社会的有色眼光是:博士生、研究生、本科生、车间工人; 重点大学高材生、普通院校、二流院校、野鸡大学; 年薪百万、五十万、五万; 这些都只是帽子,可以失败千百次,但我和社会都觉得,人只要成功一次,就能换一顶帽子,只是社会看不见你之前的失败的帽子。 当然,换帽子决不是最终目的,走好自己的路就行。 杭州.大话西游 *******/
  • 相关阅读:
    链表基础及常见面试题
    浅谈一个网页打开的全过程(涉及DNS、CDN、Nginx负载均衡等)
    PHP函数高级(二)
    sql注入笔记
    PHPStorm2017去掉参数提示 parameter name hints
    CDN与智能DNS原理和应用
    用户黏性与垂直社区,互联网营销 狼人:
    我在赶集网的两个月(完整版),互联网营销 狼人:
    微博变种与RSS变种,互联网营销 狼人:
    从 Reddit 学到的经验,互联网营销 狼人:
  • 原文地址:https://www.cnblogs.com/happybirthdaytoyou/p/13726924.html
Copyright © 2011-2022 走看看