1. 程式人生 > 其它 >C++學習記錄(十二)訊號與槽程式設計

C++學習記錄(十二)訊號與槽程式設計

 1 #include <iostream>
 2 #include <vector>
 3 
 4 using namespace std;
 5 
 6 template <class TParam>
 7 class SlotBase
 8 {
 9 public:
10     virtual void slotFunction(TParam param) = 0;
11     virtual ~SlotBase() = default;
12 };
13 
14 template <class TRecver, class TParam>
15
class Slot : public SlotBase<TParam> 16 { 17 private: 18 TRecver* m_pRecver; // 接受者的指標 19 void (TRecver::*m_func)(TParam param); // 接收者類中的成員函式指標 20 21 public: 22 Slot(TRecver* pObj, void(TRecver::*func)(TParam)) 23 { 24 this->m_pRecver = pObj; 25
this->m_func = func; 26 } 27 void slotFunction(TParam param) override 28 { 29 (m_pRecver->*m_func)(param); 30 } 31 }; 32 33 template <class TParam> 34 class Signal 35 { 36 public: 37 vector<SlotBase<TParam>*> signal_vector; 38 39 public:
40 template<class TRecver> 41 void addSlot(TRecver* pObj, void (TRecver::*func)(TParam)) 42 { 43 signal_vector.push_back(new Slot<TRecver,TParam>(pObj,func)); 44 } 45 46 void operator() (TParam param) 47 { 48 for(SlotBase<TParam>* p : signal_vector) 49 { 50 p->slotFunction(param); 51 } 52 } 53 }; 54 55 class Recver1 56 { 57 public: 58 void func1(int param) { cout << "Recver1 :" << param << endl; } 59 }; 60 61 class Recver2 62 { 63 public: 64 void func2(int param) { cout << "Recver2 :" << param << endl; } 65 }; 66 67 class SendObj 68 { 69 public: 70 Signal<int> valueChanged; 71 public: 72 void testSignal(int value) { valueChanged(value); } 73 }; 74 75 #define connect(sender, signal, recver, method) (sender)->signal.addSlot(recver, method) 76 77 int main() 78 { 79 Recver1* r1 = new Recver1; 80 Recver2* r2 = new Recver2; 81 82 SendObj* sd = new SendObj; 83 84 connect(sd, valueChanged, r1, &Recver1::func1); 85 connect(sd, valueChanged, r2, &Recver2::func2); 86 87 sd->testSignal(1000); 88 89 cout << "Hello World!" << endl; 90 return 0; 91 }