C++学习 boost学习之-Signals

来源:互联网 发布:魔兽6.2数据库 编辑:程序博客网 时间:2024/05/17 18:25

要点:

1 函数和函数对象的灵活多点回调

2健壮的触发器及事件处理的机制

3兼容于函数对象工厂,如 Boost.BindBoost.Lambda

4 Boost.Signals 库具体化了信号(signals)和插槽(slots),信号指的是某种可被"抛出"的东西,而插槽是接收该信号的连接者。这是一种著名的设计模式,它还有另外一些名字Observer, signals/slots, publisher/subscriber, events (event targets),这些名字指的都是同一个东西,指的是一些信息源和某些对这些信息的变化感兴趣的实例之间的一对多关系。

5 实现原理本质上是把函数转换为函数对象,然后存储到内部数组当中,当触发的时候,按照数组中的顺序一个一个的调用;

6 例子:

#include <iostream>
#include "boost/signals.hpp"

void my_first_slot() {
std::cout << "void my_first_slot()\n";
}

class my_second_slot {
public:
void operator()() const {
std::cout <<
"void my_second_slot::operator()() const\n";
}
};

int main() {
boost::signal<void ()> sig;

sig.connect(&my_first_slot);
sig.connect(my_second_slot());

std::cout << "Emitting a signal...\n";
sig();
}

7插槽分组

8用 Bind 和 Lambda 创建插槽

9 连接管理

boost::signal::connect 会返回一个 boost::signals::connection 实例。通过使用这个 connection 对象,就可以从 signal 断开一个插槽,也可以测试一个插槽是否已连接到signal. connection 是到 signal 和插槽间的实际链接的一个句柄。

boost::signal<void (const std::string&)> sig;

some_slot_type sc1("sc1");
some_slot_type sc2("sc2");

boost::signals::connection c1=sig.connect(sc1);
boost::signals::connection c2=sig.connect(sc2);
if (c1.connected())
std::cout << "c1 is connected to a signal\n";

// 交换并断开
sig("Hello there");
c1.swap(c2);
sig("We've swapped the connections");
c1.disconnect();
sig("Disconnected c1, which referred to sc2 after the swap");
断开连接意味着在 signal 产生时,该插槽不再被通知

10  scoped_connection

有些时候,一个插槽的 connection 的生存期只限于某一段特定代码的范围。这种情况类似于其它资源要求仅限于某个特定范围时,通常可以使用智能指针或其它作用域机制来处理。Boost.Signals 提供了connection 的一个作用域版本,名为 scoped_connection. scoped_connection 确保该connectionscoped_connection 被销毁时断开连接。

class slot {
public:
void operator()() const {
std::cout << "Something important just happened!\n";
}
};
boost::signal<void ()> sig;
{
boost::signals::scoped_connection s=sig.connect(slot());
}
sig();

这是一个伟大的库!


0 0