C++模拟实现QT信号槽
为了看着更像QT的信号槽,我们也定义一个QObject的父类。
class QObject
{
public:
QObject* self()
{
return this;
}
std::function<QObject* (void)> _sender;
};
信号的接收者
class Slot :public QObject
{
public:
Slot() {}
public:
void slot1(void* signal)
{
double res = *(reinterpret_cast<double*>(signal));
if (_sender) {
}
std::cout << "信号发送的参数 :" << res << " 接收者地址 :" << this << std::endl;
}
void slot2(void* signal) {
double res = *(reinterpret_cast<double*>(signal));
if (_sender) {
}
std::cout << "信号发送的参数 :" << res << " 接收者地址 :" << this << std::endl;
}
};
信号的发送者
class Signal :public QObject
{
public:
void emitsignal(void *signal)
{
_recver->_sender = std::bind(&Signal::self, this);
string tres = __FUNCTION__;
tres += "(";
tres += typeid(signal).name();
tres += ")";
for (map<string, vector<function<void(Slot*, void*)>>>::iterator iter = callbacks.begin(); iter != callbacks.end(); iter++) {
if (strcmp(iter->first.c_str(), tres.c_str()) == 0) {
for (int i = 0; i < iter->second.size(); i++) {
iter->second[i](_recver, signal);
}
}
}
}
map<string, vector<function<void(Slot*, void*)>>> callbacks;
Slot* _recver;
};
连接函数Connect
void connect(Signal* sender, string signal, Slot* recver, function<void(Slot*, void*)> slot)
{
sender->_recver = recver;
sender->callbacks[signal].push_back(slot);
}
所有代码及测试用例
#include <functional>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
#define SIG(x) const_cast<void*>(reinterpret_cast<void*>(x))
class QObject
{
public:
QObject* self()
{
return this;
}
std::function<QObject* (void)> _sender;
};
class Slot :public QObject
{
public:
Slot() {}
public:
void slot1(void* signal)
{
double res = *(reinterpret_cast<double*>(signal));
if (_sender) {
}
std::cout << "信号发送的参数 :" << res << " 接收者地址 :" << this << std::endl;
}
void slot2(void* signal) {
double res = *(reinterpret_cast<double*>(signal));
if (_sender) {
}
std::cout << "信号发送的参数 :" << res << " 接收者地址 :" << this << std::endl;
}
};
class Signal :public QObject
{
public:
void emitsignal(void* signal)
{
_recver->_sender = std::bind(&Signal::self, this);
string tres = __FUNCTION__;
tres += "(";
tres += typeid(signal).name();
tres += ")";
for (map<string, vector<function<void(Slot*, void*)>>>::iterator iter = callbacks.begin(); iter != callbacks.end(); iter++) {
if (strcmp(iter->first.c_str(), tres.c_str()) == 0) {
for (int i = 0; i < iter->second.size(); i++) {
iter->second[i](_recver, signal);
}
}
}
}
map<string, vector<function<void(Slot*, void*)>>> callbacks;
Slot* _recver;
};
void connect(Signal* sender, string signal, Slot* recver, function<void(Slot*, void*)> slot)
{
sender->_recver = recver;
sender->callbacks[signal].push_back(slot);
}
int main()
{
Signal signalobject;
Slot slotobject;
connect(&signalobject, "Signal::emitsignal(void *)", &slotobject, &Slot::slot1);
connect(&signalobject, "Signal::emitsignal(void *)", &slotobject, &Slot::slot2);
double param = 10.25;
signalobject.emitsignal(SIG(¶m));
return 0;
}
结果
|