c++ 中的事件机制 boost signal

c#的事件用起来多方便,c++没有现成的,boost signal 倒是比较方便:

以下是转载:

https://blog.csdn.net/zengraoli/article/details/9697841

signals2基于Boost的另一个库signals,实现了线程安全的观察者模式。在signals2库中,观察者模式被称为信号/插槽(signals and slots),他是一种函数回调机制,一个信号关联了多个插槽,当信号发出时,所有关联它的插槽都会被调用。

 

许多成熟的软件系统都用到了这种信号/插槽机制(另一个常用的名称是事件处理机制:event/event handler),它可以很好地解耦一组互相协作的类,有的语言设置直接内建了对它的支持(如c#),signals2以库的形式为c++增加了这个重要的功能。

 

1、操作函数

signal最重要的操作函数是插槽管理connect()函数,它吧插槽连接到信号上,相当于为信号(事件)增加了一个处理的handler。

插槽可以是任意的可调用对象,包括函数指针、函数对象、以及它们的bind表达式和function对象,signal内部使用function作为容器来保存这些可调用对象。连接时可以指定组号也可以不指定组号,当信号发生时将依据组号的排序准则依次调用插槽函数。

如果连接成功connect()将返回一个connection,表示了信号与插槽之间的连接关系,它是一个轻量级的对象,可以处理两者间的连接,如断开、重连接、或者测试连接状态。

成员函数disconnect()可以断开插槽与信号的连接,它有两种形式:传递组号将断开该组的所有插槽,传递一个插槽对象将仅断开该插槽。函数disconnect_all_slots()可以一次性断开信号的所有插槽连接。

2、插槽的连接于使用

signal就像一个增强的function对象,它可以容纳(使用connect())多个符合模板参数中函数签名类型的函数(插槽),形成一个插槽链表,然后在信号发生时一起调用:

 

 
  1. #include "stdafx.h"

  2. #include "boost/utility/result_of.hpp"

  3. #include "boost/typeof/typeof.hpp"

  4. #include "boost/assign.hpp"

  5. #include "boost/ref.hpp"

  6. #include "boost/bind.hpp"

  7. #include "boost/function.hpp"

  8. #include "boost/signals2.hpp"

  9. #include "iostream"

  10. using namespace std;

  11.  
  12.  
  13. void slots1()

  14. {

  15. cout << "slots1 call" << endl;

  16. }

  17.  
  18. void slots2()

  19. {

  20. cout << "slots2 call" << endl;

  21. }

  22.  
  23.  
  24. struct Hello

  25. {

  26. void operator()() const

  27. {

  28. std::cout << "Hello";

  29. }

  30. };

  31.  
  32. int _tmain(int argc, _TCHAR* argv[])

  33. {

  34. boost::signals2::signal<void()> sig;

  35. sig.connect(&slots1);

  36. sig.connect(&slots2);

  37.  
  38. sig();

  39.  
  40. boost::signals2::signal<void ()> sig1;

  41.  
  42. sig1.connect(Hello());

  43. sig1();

  44.  
  45.  
  46. return 0;

  47. }

 

 

注:编译这个程序的时候,确保已经在stdafx.h中加入#define _SCL_SECURE_NO_WARNINGS或者,在C/C++----预处理器----预处理器定义中加上了_SCL_SECURE_NO_WARNINGS,否则会引发错误(或不能正确输出),下同。

在连接插槽时省了了connect()的第二个参数connect_position,它的缺省值是at_back,表示插槽将插入到信号插槽链表的尾部,因此slot2将在slot1之后被调用。

 

下面是使用和组号的情况:

 
  1. #include "stdafx.h"

  2. #include "boost/utility/result_of.hpp"

  3. #include "boost/typeof/typeof.hpp"

  4. #include "boost/assign.hpp"

  5. #include "boost/ref.hpp"

  6. #include "boost/bind.hpp"

  7. #include "boost/function.hpp"

  8. #include "boost/signals2.hpp"

  9. #include "iostream"

  10. using namespace std;

  11.  
  12.  
  13. template<int N>

  14. struct Slot

  15. {

  16. void operator()()

  17. {

  18. cout << "Slot current N value is : " << N << endl;

  19. }

  20. };

  21.  
  22.  
  23. int _tmain(int argc, _TCHAR* argv[])

  24. {

  25. boost::signals2::signal<void()> sig;

  26.  
  27. sig.connect(Slot<1>(), boost::signals2::at_back); // 最后一个被调用

  28. sig.connect(Slot<99>(), boost::signals2::at_front); // 第一个被调用

  29.  
  30. sig.connect(5, Slot<55>(), boost::signals2::at_back); // 组号5的最后一个

  31. sig.connect(5, Slot<57>(), boost::signals2::at_front);// 组号5的第一个

  32.  
  33. sig.connect(10, Slot<100>());// 组号10该组只有一个

  34.  
  35. sig();

  36.  
  37. return 0;

  38. }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值