boost之signal的封装及使用例子
封装:
#ifndef SIGNAL_H
#define SIGNAL_H#include <boost/signals2.hpp>
#include <functional>
#include <mutex>template<typename Signature>
class Signal {
public:using SignalType = boost::signals2::signal<Signature>;using SlotType = typename SignalType::slot_type;using Connection = boost::signals2::connection;using ScopedConnection = boost::signals2::scoped_connection;Signal() = default;~Signal() = default;Signal(const Signal&) = delete;Signal& operator=(const Signal&) = delete;Signal(Signal&&) = delete;Signal& operator=(Signal&&) = delete;// 连接槽函数Connection connect(const SlotType& slot) {std::lock_guard<std::mutex> lock(mutex_);return signal_.connect(slot);}// 作用域连接(自动管理生命周期)ScopedConnection connect_scoped(const SlotType& slot) {std::lock_guard<std::mutex> lock(mutex_);return ScopedConnection(signal_.connect(slot));}// 断开连接(无锁优化)void disconnect(Connection conn) {conn.disconnect();}// 断开所有连接void disconnect_all() {std::lock_guard<std::mutex> lock(mutex_);signal_.disconnect_all_slots();}// 线程安全的信号发射template<typename... Args>void emit(Args&&... args) {SignalType tmp;{std::lock_guard<std::mutex> lock(mutex_);tmp = signal_; // 复制槽列表}tmp(std::forward<Args>(args)...); // 在锁外执行}// 获取连接数size_t connection_count() const {std::lock_guard<std::mutex> lock(mutex_);return signal_.num_slots();}private:SignalType signal_;mutable std::mutex mutex_;
};#endif // SIGNAL_H
例子:
#include <iostream>
#include <string>
#include "Signal.h"using MySignal = Signal<void(int, const std::string&)>;void freeFunction(int a, const std::string& str) {std::cout << "[FreeFunction] a=" << a << ", str=" << str << std::endl;
}class MyClass {
public:void memberFunction(int a, const std::string& str) {std::cout << "[MyClass::memberFunction] a=" << a << ", str=" << str << std::endl;}
};int main() {MySignal signal;// 连接自由函数auto conn1 = signal.connect(&freeFunction);MyClass obj;// 连接成员函数auto conn2 = signal.connect(std::bind(&MyClass::memberFunction, &obj, std::placeholders::_1, std::placeholders::_2));// 连接lambda,使用作用域连接自动断开{auto scopedConn = signal.connect_scoped([](int a, const std::string& str) {std::cout << "[Lambda Scoped] a=" << a << ", str=" << str << std::endl;});std::cout << "连接数: " << signal.connection_count() << std::endl;// 发送信号signal.emit(10, "Hello World");// scopedConn 离开作用域后自动断开}std::cout << "连接数(lambda断开后): " << signal.connection_count() << std::endl;// 再次发送信号,lambda槽不会被调用signal.emit(20, "After Scoped Disconnect");// 手动断开自由函数连接signal.disconnect(conn1);std::cout << "连接数(自由函数断开后): " << signal.connection_count() << std::endl;// 发送信号,只剩成员函数槽被调用signal.emit(30, "Only Member Function");// 断开所有连接signal.disconnect_all();std::cout << "连接数(全部断开后): " << signal.connection_count() << std::endl;// 发送信号,不会有任何输出signal.emit(40, "No listeners");return 0;
}