前言
通过纯C++代码编写类似QT的信号槽功能。其实就是观察者模式。
#include <iostream>
#include <vector>
using namespace std;
template <typename TParam>
class SlotBase
{
public:
virtual void slotFunction(TParam param) = 0;
~SlotBase() = default;
};
template <typename TRecver, typename TParam>
class Slot : public SlotBase<TParam>
{
private:
typedef void (TRecver::*Call_Back)(TParam);
TRecver* m_pRecver;
Call_Back m_func;
public:
Slot(TRecver* pObj, Call_Back func)
{
this->m_pRecver = pObj;
this->m_func = func;
}
~Slot(){}
public:
virtual void slotFunction(TParam param)override
{
(this->m_pRecver->*m_func)(param);
}
};
// signal
template<typename TParam>
class Signal
{
public:
Signal(){}
~Signal(){}
public:
template<typename TRecver>
void addSlot(TRecver* pObj, void (TRecver::*func)(TParam ))
{
m_vecSignalSlot.push_back(new Slot<TRecver,TParam>(pObj,func));
}
void operator()(TParam param)
{
for(SlotBase<TParam>*p : m_vecSignalSlot)
{
p->slotFunction(param); // 最好可变参
}
}
private:
std::vector<SlotBase<TParam>*> m_vecSignalSlot;
};
class RecverA
{
public:
void func(int param)
{
std::cout << "Test RecverA param: " << param << std::endl;
}
};
class RecverB
{
public:
void func(int param)
{
std::cout << "Test RecverB param: " << param << std::endl;
}
};
class SendObj
{
public:
SendObj(){}
~SendObj(){}
public:
void test_signal(int value)
{
valueChanged(value);
}
public:
Signal<int> valueChanged;
};
#define connect(sender,signal,recver,method) (sender)->signal.addSlot(recver,method)
int main()
{
RecverA* r1 = new RecverA;
RecverB* r2 = new RecverB;
SendObj *sd = new SendObj;
connect(sd, valueChanged, r1, &RecverA::func);
connect(sd, valueChanged, r2, &RecverB::func);
sd->test_signal(123);
return 0;
}