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的第一个参数是设置槽函数的优先级,数字越大的槽函数的优先级越低,越靠后执行。所有的槽函数都会被执行,只有最后一个槽函数的返回值作为最终的返回值返回给信号。
.
Boost 信号与槽,获取槽函数返回值,使用占位参数传递信号携带的参数的更多相关文章
- python使用threading获取线程函数返回值的实现方法
python使用threading获取线程函数返回值的实现方法 这篇文章主要介绍了python使用threading获取线程函数返回值的实现方法,需要的朋友可以参考下 threading用于提供线程相 ...
- Python从线程获取函数返回值
Python中利用强大的threading模块可以很容易的实现多线程开发,提高运行速度.这一般是对某个进行大量计算操作的的函数进行多线程处理,然后合并各线程的结果.获取函数返回值的方法可以如下: 1) ...
- PHP获取函数返回值的引用
通过在函数前添加&可以获取函数返回值的引用,如:function &test(){return 10;}
- Shell $?获取函数返回值或者上一个命令的退出状态
Shell $?获取函数返回值或者上一个命令的退出状态 来自:互联网 时间:2021-01-12 阅读:2 $? 是一个特殊变量,用来获取上一个命令的退出状态,或者上一个函数的返回值. 所谓退出状态, ...
- c++11之获取模板函数的参数个数和函数返回值类型
本文演示c++需要支持c++11及以上标准 获取参数个数 1.模板函数声明 template <class R, class... Args> R getRetValue(R(*)(Arg ...
- shell调用函数返回值深入分析
编写shell脚本过程中,我们经常会自定义一些函数,并根据函数的返回值不同来执行相应的流程,那么我们如何来获取函数的返回值呢? 首先shell中调用函数有两种方式: 第一种:value=`functi ...
- c语言main函数返回值、参数详解(返回值是必须的,0表示正常退出)
C语言Main函数返回值 main函数的返回值,用于说明程序的退出状态.如果返回0,则代表程序正常退出:返回其它数字的含义则由系统决定.通常,返回非零代表程序异常退出. 很多人甚至市面上的一些书籍,都 ...
- [转]system函数返回值探究
对于system这个函数的功能早就有一定了解,读书期间,就学习了UNIX系统编程这本书,后来买了APUE.我这个人总是有好读书不求甚解的毛病.对于system函数只知其一,不知其二.后来被人问起相关的 ...
- Linux Shell 函数返回值
Shell函数返回值,常用的两种方式:return,echo 1) return 语句 shell函数的返回值,可以和其他语言的返回值一样,通过return语句返回. 示例: #!/bin/sh fu ...
- Linux Shell函数返回值
转:http://blog.csdn.net/ithomer/article/details/7954577 Shell函数返回值,一般有3种方式:return,argv,echo 1) return ...
随机推荐
- 由浅入深理解 IOC 和 DI
目录 由浅入深理解 IOC 和 DI 开闭原则 OCP(Open Closed Principle) 面向抽象编程 逐步理解实现 IOC 和 DI 的过程(LOL Demo 示例) 比较尴尬的编写程序 ...
- Excel-时间函数将时间换成小时
问题场景 用考勤打卡时间算员工饱和度. 场景 计算员工实际工作时长,需要算出打卡时长再减去午休时长1.5小时. 目标 算出实际工作时长. 解决方案 利用单元格格式设置进行简单计算. 第一步:在F2单元 ...
- 网络请求以及网络请求下载图片的工具类 android开发java工具类
package cc.jiusan.www.utils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; ...
- cookies、sessionStorage和localStorage
浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互.浏览器查看方式: HTML4的本地存储 cookie 一.cookie和sess ...
- 面试【JAVA基础】阻塞队列
1.五种阻塞队列介绍 ArrayBlockingQueue 有界队列,底层使用数组实现,并发控制使用ReentrantLock控制,不管是插入操作还是读取操作,都需要获取锁之后才能执行. Linked ...
- istio部署
Istio的部署介绍 目录 Istio的部署介绍 部署模型 集群模式 单集群 多集群 网络模型 单网络 多网络 控制面模型 身份和信任模型 网格中的信任 网格之间的信任 网格模型 单网格 多网格 租户 ...
- 小程序mpvue中flyio的使用方法
Fly.js 一个基于Promise的.强大的.支持多种JavaScript运行时的http请求库. 有了它,您可以使用一份http请求代码在浏览器.微信小程序.Weex.Node.React Nat ...
- Java8 ParallelStream
ParallelStream 并行流就是一个把内容拆分成多个数据块,用不同线程分别处理每个数据块的流.对收集源调用parallelStream方法就能将集合转换为并行流. 并行流 并行流和顺序流转换 ...
- 在Win10上安装Apache2.44
下载地址:https://www.apachelounge.com/download/VS16/binaries/httpd-2.4.41-win64-VS16.zip 如果以上地址失效请到 http ...
- ARM函数调用总结
ARM架构寄存器介绍 ARM架构下处理器有7种工作模式: 1. USR模式:正常用户模式,在USR模式下进程正常执行 2. FIQ模式(Fast Interrupt Request):处理快速中断模式 ...