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