C++實現訊號和槽機制
阿新 • • 發佈:2019-02-02
主要通過,C++實現型別QT訊號和槽的問題
設計思路:
1、利於模板函式和模板類的通用性
2、bind的時候,將槽函式指標儲存,觸發時呼叫
程式碼如下:
#include <algorithm> #include <iostream> #include <vector> using namespace std; #define Connect(sender, signal, receiver, method) ((sender)->signal.Bind(receiver, method)) /* * func: 槽函式基類 * parm: * return: */ template<class T> class SlotBase { public: virtual void Exec(T param1) = 0; //純虛擬函式 virtual ~SlotBase(){} }; /* * func: 槽函式 * parm: * return: */ template<class T, class T1> class Slot : public SlotBase<T1> { public: /* 定義Slot的時候,獲取槽函式資訊 */ Slot(T* pObj, void (T::*func)(T1)) { m_pSlotBase = pObj; m_Func = func; } /* signal觸發時,呼叫 */ void Exec(T1 param1) { (m_pSlotBase->*m_Func)(param1); } private: /* 槽函式資訊 暫存 */ T* m_pSlotBase = NULL; void (T::*m_Func)(T1); }; /* * func: 訊號 * parm: * return: */ template<class T1> class Signal { public: /* 模板函式 -> Bind時獲取槽函式指標 */ template<class T> void Bind(T* pObj, void (T::*func)(T1)) { m_pSlotSet.push_back(new Slot<T,T1>(pObj,func)); } /* 過載操作符 -> signal觸發機制 */ void operator()(T1 param1) { for(int i=0;i<(int)m_pSlotSet.size();i++) { m_pSlotSet[i]->Exec(param1); } } ~Signal() { for(int i=0;i<(int)m_pSlotSet.size();i++) { delete m_pSlotSet[i]; } } private: vector<SlotBase<T1>*> m_pSlotSet; //這一句很重要,靠基類的指標來儲存 訊號槽指標 }; class TestFunc1 { public: void FuncOfA(int parm) { printf("enter FuncOfA parm = %d\n", parm); } }; class TestFunc2 { public: void FuncOfB(int parm) { printf("enter FuncOfB parm = %d\n", parm); } }; class TestSignal { public: TestSignal() { } void emit(int value) { ValueChanged(value); } public: Signal<int> ValueChanged; }; int main() { /* 1、定義訊號和槽 */ TestFunc1* pFunc1 = new TestFunc1; TestFunc2* pFunc2 = new TestFunc2; TestSignal* pSignal = new TestSignal; /* 2、1個訊號繫結2個槽 */ Connect(pSignal, ValueChanged, pFunc1, &TestFunc1::FuncOfA); Connect(pSignal, ValueChanged, pFunc2, &TestFunc2::FuncOfB); /* 3、觸發訊號 */ pSignal->emit(1); pSignal->emit(2); delete pFunc1; delete pFunc2; delete pSignal; }