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 ...
随机推荐
- 从String类型发散想到的一些东西
值类型 引用类型 值类型表示存储在栈上的类型,包括简单类型(int.long.double.short).枚举.struct定义: 引用类型表示存在堆上的类型,包括数组.接口.委托.class定义: ...
- CCAI观后
暑期和大老板的学生一起学了一暑假的计算机视觉和机器学习,以前只是在京畿范围的学校听到的报告和这阵的学习数量级都不同.当时看到了很多人的报告,忽然发现了做报告应该做的准备实际还有很多. 首先是要有充分的 ...
- 23种设计模式 - 对象性能(Singleton - Flyweight享元)
其他设计模式 23种设计模式(C++) 每一种都有对应理解的相关代码示例 → Git原码 ⌨ 对象性能 面向对象很好地解决了"抽象"的问题,但是必不可免地付出一定的代价.对于通常情 ...
- type类型为number的input标签可以输入字母e
主要原因是:e在数学上代表的是无理数,是一个无限不循环的小数,其值约为2.7182818284,所以在输入e的时候,输入框会把e当成一个数字看待. 可以采用下面的方式来避免这个BUG,在input标签 ...
- Android Studio出现:Your project path contains non-ASCII 错误代码解决方法
导入Project的出现: Error:(1, 0) Your project path contains non-ASCII characters. This will most likely ca ...
- Pytest allure自定义特性场景功能
@allure.feature @allure.story allure支持用户对测试用例进行功能模块的自定义,并展示在报告中 需要在测试用例代码中加上装饰器@allure.feature[加在测试类 ...
- 使用Unity的50个建议
关于这些建议 这些建议并不适用于所有的项目 这些建议是基于我与3-20人的小团队项目经验总结出来的 结构.可重复使用性.明晰度都是有价的——团队规模和项目规模决定了是否值得付这个价. 一些建议也许公然 ...
- The Triangle (简单动态规划)
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1) Figure 1 shows a number triangle. Write a program that calc ...
- java初探(1)之防止库存为负以及防超买
在秒杀业务中,会出现当只剩一个库存时,但有多个人仍然秒杀成功,且都减库存成功,因此,在减库存,更新数据库的时候,需要在sql语句上进行判断,是否库存大于0. @Update("update ...
- eslint prettier vetur eslint
VScode (版本 1.47.3)安装 eslint prettier vetur 插件 .vue 文件使用 vetur 进行格式化 在文件 .prettierrc 里写 属于你的 pettier ...