背景
Qt的信号槽是常用的,但是对于非GUI的部分,最好还是用纯C++的好些,毕竟如果需要将现有的代码直接作为SDK给第三方公司同事使用,还是纯C++的好些。基于此,了解到C++的一个信号槽类库——sigslot。
sigslot的优势
- 仅需要include其头文件即可,无需lib、dll文件
- 使用方便
- 定义信号
- 定义槽函数 //实现槽的类必须继承has_slots<>
- 关联信号和槽函数
- 发送信号
- 断开信号
- 发送未connect的信号不会报错
sigslot的劣势
- 信号传递的参数数量有限(0-8个),
- 当然8个参数绝可以应对绝大多数场景,如果传递的参数过多时,需要考虑是否可以封装,封装成stuct、Class
- 槽函数的返回值为void
talk is cheap, show me the code
#include <iostream>
#include "sigslot.h"
using namespace sigslot;
struct People
{
int age;
std::string name;
};
class Switch
{
public:
signal0<> sig_turnOn;
signal1<std::string> sig_SendText;
signal1<struct People> sig_SendPeople;//测试发送结构体,以应对参数过多的情景
};
class Light : public has_slots<>
{
public:
void slot_TurnOn()
{
std::cout << "the light is on\n";
}
void slot_ReceiveText(std::string s)
{
std::cout << "received message :"<<s <<"\n";
}
void slot_receivePeople(struct People p)
{
std::cout << "received People, age = "<<p.age<<" name = "<<p.name << "\n";
}
};
int main(int argc, char *argv[])
{
Light light;
Switch sw;
sw.sig_turnOn.connect(&light, &Light::slot_TurnOn);//关联信号
sw.sig_turnOn();//发送信号
sw.sig_turnOn.emit();//发送信号的另一种方式
sw.sig_SendText.connect(&light, &Light::slot_ReceiveText);
sw.sig_SendText("hello world");//发送信号
sw.sig_SendText.emit("hello sigslot");//发送信号的另一种方式
std::cout << "disconnect clicked signal before" << std::endl;
sw.sig_turnOn.disconnect(&light);//断开信号连接
sw.sig_turnOn.emit();//此时发送信号不会报错
std::cout << "disconnect clicked signal end" << std::endl;
sw.sig_turnOn.connect(&light, &Light::slot_TurnOn);//再次关联信号
sw.sig_turnOn.emit();
sw.sig_turnOn.disconnect_all();//断开所有与该信号关联的槽函数
sw.sig_SendPeople.connect(&light, &Light::slot_receivePeople);
People p{ 18,"sunny" };
sw.sig_SendPeople(p);
system("pause");
return 0;
}