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 信号与槽,获取槽函数返回值,使用占位参数传递信号携带的参数的更多相关文章

  1. python使用threading获取线程函数返回值的实现方法

    python使用threading获取线程函数返回值的实现方法 这篇文章主要介绍了python使用threading获取线程函数返回值的实现方法,需要的朋友可以参考下 threading用于提供线程相 ...

  2. Python从线程获取函数返回值

    Python中利用强大的threading模块可以很容易的实现多线程开发,提高运行速度.这一般是对某个进行大量计算操作的的函数进行多线程处理,然后合并各线程的结果.获取函数返回值的方法可以如下: 1) ...

  3. PHP获取函数返回值的引用

    通过在函数前添加&可以获取函数返回值的引用,如:function &test(){return 10;}

  4. Shell $?获取函数返回值或者上一个命令的退出状态

    Shell $?获取函数返回值或者上一个命令的退出状态 来自:互联网 时间:2021-01-12 阅读:2 $? 是一个特殊变量,用来获取上一个命令的退出状态,或者上一个函数的返回值. 所谓退出状态, ...

  5. c++11之获取模板函数的参数个数和函数返回值类型

    本文演示c++需要支持c++11及以上标准 获取参数个数 1.模板函数声明 template <class R, class... Args> R getRetValue(R(*)(Arg ...

  6. shell调用函数返回值深入分析

    编写shell脚本过程中,我们经常会自定义一些函数,并根据函数的返回值不同来执行相应的流程,那么我们如何来获取函数的返回值呢? 首先shell中调用函数有两种方式: 第一种:value=`functi ...

  7. c语言main函数返回值、参数详解(返回值是必须的,0表示正常退出)

    C语言Main函数返回值 main函数的返回值,用于说明程序的退出状态.如果返回0,则代表程序正常退出:返回其它数字的含义则由系统决定.通常,返回非零代表程序异常退出. 很多人甚至市面上的一些书籍,都 ...

  8. [转]system函数返回值探究

    对于system这个函数的功能早就有一定了解,读书期间,就学习了UNIX系统编程这本书,后来买了APUE.我这个人总是有好读书不求甚解的毛病.对于system函数只知其一,不知其二.后来被人问起相关的 ...

  9. Linux Shell 函数返回值

    Shell函数返回值,常用的两种方式:return,echo 1) return 语句 shell函数的返回值,可以和其他语言的返回值一样,通过return语句返回. 示例: #!/bin/sh fu ...

  10. Linux Shell函数返回值

    转:http://blog.csdn.net/ithomer/article/details/7954577 Shell函数返回值,一般有3种方式:return,argv,echo 1) return ...

随机推荐

  1. IDEA 左侧出现对勾,该如何去掉对勾呢?

    如下面 解决办法如下 单击按F11 或者ctrl +鼠标左键点击那个对串就可以决你的问题 有对勾是因为你把他添加进去了书签,方便下次自己看 我们可以在这个地方看到自己的书签也就是打对勾的地方

  2. day46:jQuery

    目录 1.jQuery初识 2.选择器 3.文本操作 4.class类值操作 5.css样式操作 6.值操作 7.注意点:button按钮提交form表单数据 8.jquery选择器补充 9.模态对话 ...

  3. leetcode刷题-90子集 II

    题目 给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: [1,2,2]输出:[ [2], [1], [1,2,2], [ ...

  4. get_started_3dsctf_2016

    题外:这道题不是很难,但是却难住了我很久.主要是在IDA中查看反编译出的伪代码时双击了一下gets()函数,结果进入gets函数内部,我当时就懵了,误以为这是一个自定义函数,但是自定义函数应该应该不能 ...

  5. centos7图形化安装oracle11g

    #设置主机名 hostnamectl set-hostname oracle #yum安装 yum -y install unzip vim* bash-completion bash-complet ...

  6. ThinkPHP6.0 多应用模式 部署 Layuiadmin 单页版

    TP6.0中的路由省略应用名只能用入口文件绑定应用 和 域名绑定应用,经过测试,最后得出域名绑定应用是最合适的部署方式.如果有更好的部署方案,欢迎分享.QQ:23426945 1. 下载TP6.0,引 ...

  7. 基于 ramfs 的 OTA

    背景 默认的 OTA 方案是基于 recovery 系统完成的.某个产品考虑产品形态和 flash 容量之后,计划去掉 recovery 系统(不考虑掉电安全),这就需要 OTA 方案能支持在只有单个 ...

  8. List和Dictionary的使用技巧总结

    List和Dictionary想必是我们平常用到最多的C#容器了,他们使用起来都很简单,所以很多人就可能就没去深究,其实在使用过程中有很多的小技巧能让我们写的代码变得更高效也更安全. 1·合理的指定初 ...

  9. C#托管堆和非托管堆

  10. Web开发初探(系统理解Web知识点)

    一.Web开发介绍 我们看到的网页通过代码来实现的 ,这些代码由浏览器解释并渲染成你看到的丰富多彩的页面效果. 这个浏览器就相当于Python的解释器,专门负责解释和执行(渲染)网页代码. 写网页的代 ...