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())多个符合模板参数中函数签名类型的函数(插槽),形成一个插槽链表,然后在信号发生时一起调用:
-
#include "stdafx.h"
-
#include "boost/utility/result_of.hpp"
-
#include "boost/typeof/typeof.hpp"
-
#include "boost/assign.hpp"
-
#include "boost/ref.hpp"
-
#include "boost/bind.hpp"
-
#include "boost/function.hpp"
-
#include "boost/signals2.hpp"
-
#include "iostream"
-
using namespace std;
-
void slots1()
-
{
-
cout << "slots1 call" << endl;
-
}
-
void slots2()
-
{
-
cout << "slots2 call" << endl;
-
}
-
struct Hello
-
{
-
void operator()() const
-
{
-
std::cout << "Hello";
-
}
-
};
-
int _tmain(int argc, _TCHAR* argv[])
-
{
-
boost::signals2::signal<void()> sig;
-
sig.connect(&slots1);
-
sig.connect(&slots2);
-
sig();
-
boost::signals2::signal<void ()> sig1;
-
sig1.connect(Hello());
-
sig1();
-
return 0;
-
}
注:编译这个程序的时候,确保已经在stdafx.h中加入#define _SCL_SECURE_NO_WARNINGS或者,在C/C++----预处理器----预处理器定义中加上了_SCL_SECURE_NO_WARNINGS,否则会引发错误(或不能正确输出),下同。
在连接插槽时省了了connect()的第二个参数connect_position,它的缺省值是at_back,表示插槽将插入到信号插槽链表的尾部,因此slot2将在slot1之后被调用。
下面是使用和组号的情况:
-
#include "stdafx.h"
-
#include "boost/utility/result_of.hpp"
-
#include "boost/typeof/typeof.hpp"
-
#include "boost/assign.hpp"
-
#include "boost/ref.hpp"
-
#include "boost/bind.hpp"
-
#include "boost/function.hpp"
-
#include "boost/signals2.hpp"
-
#include "iostream"
-
using namespace std;
-
template<int N>
-
struct Slot
-
{
-
void operator()()
-
{
-
cout << "Slot current N value is : " << N << endl;
-
}
-
};
-
int _tmain(int argc, _TCHAR* argv[])
-
{
-
boost::signals2::signal<void()> sig;
-
sig.connect(Slot<1>(), boost::signals2::at_back); // 最后一个被调用
-
sig.connect(Slot<99>(), boost::signals2::at_front); // 第一个被调用
-
sig.connect(5, Slot<55>(), boost::signals2::at_back); // 组号5的最后一个
-
sig.connect(5, Slot<57>(), boost::signals2::at_front);// 组号5的第一个
-
sig.connect(10, Slot<100>());// 组号10该组只有一个
-
sig();
-
return 0;
-
}