boost库的signals使用

signals的使用其实就是实现了观察者模式。

两个关键词:signal 和 slots ——信号插槽

信号其实就是Subject,插槽就是Observer

给信号连接上插槽,然后信号一触发,插槽上的函数就一触即发。

一个简单的使用signal和slots的例子:

1.先定义一个函数对象HelloWorld

(函数对象就是实现了operator()操作符的类)

struct HelloWorld 
{
        void operator()() const 
       { 
             std::cout << "Hello, World!" << std::endl;
       } 
};

2.定义信号signal类型的变量 sig 

boost::signal<返回值 + 输入参数>

boost::signal<void ()> sig;

3.使用connect方法

connect的作用是将一个函数对象实例hello,连接到sig。如下:

HelloWorld hello;
sig.connect(hello);

也可以用

sig.connect(HelloWorld());   // 调用HelloWord的默认构造函数  构造了一个HelloWord对象实例

上述的hello即为连接到signal的一个slot

  • slot除了可以是函数对象,也可以是函数指针:
void print_sum(float x, float y)
{
  std::cout << "The sum is " << x+y << std::endl;
}
boost::signal<void (float, float)> sig;

sig.connect(&print_sum);

sig(5, 3);
  • 一个signal可以连接多个slot

多个slot也可以是相同的。顺序一般先进先调用,但是也有可能有副作用。

void print_sum(float x, float y)
{
  std::cout << "The sum is " << x+y << std::endl;
}
boost::signal<void (float, float)> sig;

sig.connect(&print_sum);
sig.connect(&print_sum);
sig(5, 3);

如果对调用顺序有严格的要求,可以调用下面这个重载函数进行connect,增加要给参数groupname,int类型的,值越小,越早调用。

connect(groupname,slot)

4.调用sig

即调用连接到自己的slots——即hello。

sig();

5.断开连接

一般slot不会永久得连接到signal,一般slot用来连接过一些事件以后就会进行断开连接。例如:

void foo();
void bar();

signal<void()> sig;

sig.connect(&foo);
sig.connect(&bar);

// disconnects foo, but not bar
sig.disconnect(&foo);

注意:函数对象的断开,需要函数对象的类型具有可访问的==运算符,即可以使用disconnect方法的形式断开与给定函数对象等效的槽。

参考

https://www.boost.org/doc/libs/1_61_0/doc/html/signals/tutorial.html

猜你喜欢

转载自blog.csdn.net/u012138730/article/details/88656800