仿QT信号与槽的简易框架

  • 信号与槽通常被用于对象间的通信、事件驱动等场景,相比于回调函数的优势是动态连接、支持多对多、参数类型检查更安全、更加松耦合等。

  • 这里提供一个C++实现的简易仿信号与槽的框架。注:QT中信号与槽是基于较复杂的元对象系统,而这里只是以基本功能为导向提供简易实现。

    信号和槽函数的创建、连接、触发、断连。

  • code

cpp 复制代码
#include <iostream>
#include <functional>
#include <vector>
#include <map>

#define CONNECT(signal, slot) signal.connect(slot, #slot)
#define DISCONNECT(signal, slot) signal.disconnect(#slot)

template <typename... Args>
class GenericSignal
{
public:
    using SlotType = std::function<void(Args...)>;

    void connect(SlotType slot, const std::string &slotName)
    {
        slots[slotName] = std::move(slot);
    }

    void disconnect(const std::string &slotName)
    {
        auto it = slots.find(slotName);
        if (it != slots.end())
        {
            slots.erase(it);
        }
    }

    template <typename... SignalArgs>
    void emitSignal(SignalArgs &&...args) const
    {
        for (const auto &slotPair : slots)
        {
            slotPair.second(std::forward<SignalArgs>(args)...);
        }
    }

private:
    std::map<std::string, SlotType> slots;
};

void slotFunction1(int arg1, const std::string &arg2)
{
    std::cout << "Slot 1 called with " << arg1 << " and " << arg2 << std::endl;
}

void slotFunction2(int arg1, const std::string &arg2)
{
    std::cout << "Slot 2 called with " << arg1 << " and " << arg2 << std::endl;
}

int main()
{
    GenericSignal<int, const std::string &> signal;

    CONNECT(signal, &slotFunction1);
    CONNECT(signal, &slotFunction2);

    std::cout << "Emitting signal..." << std::endl;
    signal.emitSignal(1, "Hello");

    DISCONNECT(signal, &slotFunction1);

    std::cout << "\nEmitting signal after disconnecting slotFunction1..." << std::endl;
    signal.emitSignal(2, "Hello");

    return 0;
}
  • result
bash 复制代码
Emitting signal...
Slot 1 called with 1 and Hello
Slot 2 called with 1 and Hello

Emitting signal after disconnecting slotFunction1...
Slot 2 called with 2 and Hello
相关推荐
老胖闲聊8 分钟前
Python Rio 【图像处理】库简介
开发语言·图像处理·python
码界奇点29 分钟前
Python Flask文件处理与异常处理实战指南
开发语言·python·自然语言处理·flask·python3.11
贩卖纯净水.38 分钟前
浏览器兼容-polyfill-本地服务-优化
开发语言·前端·javascript
weixin_4786897638 分钟前
C++ 对 C 的兼容性
java·c语言·c++
k要开心44 分钟前
C++概念以及基础框架语法
开发语言·c++
weixin_307779131 小时前
Linux下GCC和C++实现统计Clickhouse数据仓库指定表中各字段的空值、空字符串或零值比例
linux·运维·c++·数据仓库·clickhouse
开发者工具分享2 小时前
如何应对敏捷转型中的团队阻力
开发语言
gregmankiw2 小时前
C#调用Rust动态链接库DLL的案例
开发语言·rust·c#
roman_日积跬步-终至千里2 小时前
【Go语言基础【20】】Go的包与工程
开发语言·后端·golang
秦少游在淮海2 小时前
C++ - string 的使用 #auto #范围for #访问及遍历操作 #容量操作 #修改操作 #其他操作 #非成员函数
开发语言·c++·stl·string·范围for·auto·string 的使用