轉自:http://www.cnblogs.com/bastard/archive/2012/01/10/2318417.html
C++ Event Model
一 事件模型
對發生的事件作出的響應——事件模型。
1 事件:
在面向對象中,就是對象的屬性或者狀態發生了變化,操作或者接收到了某些動作時,
向外發出了這種變化或者動作對應的通知。
2 事件模型包括的元素:
3 事件模型過程:
二 代碼實現
1 EventManager
/*----------------------------------------------------------------*/ /* class Object 響應事件函數的類必須是從Object派生下來 */ /*----------------------------------------------------------------*/ class Object { }; /*----------------------------------------------------------------*/ /* class Event 模板參數為 返回類型 和響應函數參數類型 */ /* 僅實現一個參數的事件響應函數 */ /*----------------------------------------------------------------*/ template<typename rtnTtpe,typename ArgType> class Event { //使每個事件最多關聯響應的函數個數 #define EVENT_LIST_MAX_NUM (10) typedef rtnTtpe (Object::*pMemFunc)(ArgType arg); public: Event() { m_totalFunc = 0; m_obj = NULL; for (int i = 0; i < EVENT_LIST_MAX_NUM; i++) { m_func[i] = NULL; } } //關聯回調成員函數 template <class _func_type> void associate(Object *obj, _func_type func) { m_obj = obj; m_func[m_totalFunc] = static_cast<pMemFunc> (func); m_totalFunc++; } //刪除事件關聯回調成員函數 template <class _func_type> void disAssociate(Object *obj, _func_type func) { if (obj != m_obj) { return; } //查找 for (int i = 0; i < m_totalFunc; i++) { if (m_func[i] == func) { break; } } //移動刪除 for (i ; i < m_totalFunc - 1; i++) { m_func[i] = m_func[i + 1]; } m_func[i] = NULL; m_totalFunc --; } //執行關聯的回調函數 void sendEvent(ArgType arg) { for (int i = 0; i < m_totalFunc; i++) { if (m_func[i] != NULL) { ((m_obj->*pMemFunc(m_func[i])))(arg); } } } private: Object* m_obj; pMemFunc m_func[EVENT_LIST_MAX_NUM]; int m_totalFunc; };
2 測試代碼
/*----------------------------------------------------------------*/ /* class TestEvent */ /*----------------------------------------------------------------*/ class TestEvent { public: void test() { //do somsthing //…… //觸發事件 myEvent.sendEvent(100); myEvent.sendEvent(200); } public: //定義事件 Event<bool,int> myEvent; };
/*----------------------------------------------------------------*/ /* class TestClass */ /*----------------------------------------------------------------*/ class TestClass:public Object { public: TestClass() { //關聯事件 m_event.myEvent.associate(this,&TestClass::executeCb1); m_event.myEvent.associate(this,&TestClass::executeCb2); } //事件響應函數 bool executeCb1(int result) { cout<<"executeCb1 result = "<<result<<endl; return true; } //事件響應函數 bool executeCb2(int result) { cout<<"executeCb2 result = "<<result<<endl; return true; } void execute() { m_event.test(); } void stop() { //刪除事件關聯函數 m_event.myEvent.disAssociate(this,&TestClass::executeCb1); } private: TestEvent m_event; };
int main() { TestClass testObj; testObj.execute(); testObj.stop(); testObj.execute(); return 0; }
3 輸出結果
<---------------first begin--------------- executeCb1 result = 100 executeCb2 result = 100 executeCb1 result = 200 executeCb2 result = 200 ---------------after delete--------------- executeCb2 result = 100 executeCb2 result = 200