背景:
对象A对对象B的某个事件E感兴趣,当B触发E时,A会作出相应的动作。A想知道B触发E的方法至少有两种:1、轮询,2、被告知。显然第二种方法是更可靠更高效的方法,它情景应该是这样的:A告诉B,当发生事件E时告诉我一下吖。B答,好吖。其实A更可以将要做的相应动作委托给B,当事件E触发时,由B去执行这样的动作,这就是我所理解的委托。
C++中委托的实现至少可以这样实现:
#include <vector> class IHandler { public: IHandler(){} virtual ~IHandler(){} public: virtual void Call(int wParam, int lParam) = 0; virtual void* GetObjectPtr() const { return NULL; }; virtual void* GetHandlerPtr() const { return NULL; }; };
template<typename TOBJECT> class MemHandler : public IHandler { public: typedef void (TOBJECT::*Handler)(int, int); public: MemHandler(){} virtual ~MemHandler(){} public: virtual void Call(int wParam, int lParam) { if (m_pObject != NULL && m_pHandler != NULL) { (m_pObject->*m_pHandler)(wParam, lParam); } } void SetObject(TOBJECT* pObject) { m_pObject = pObject; } void SetHandler(Handler pHandler) { m_pHandler = pHandler; } virtual void* GetObjectPtr() const { return (void*)m_pObject; } virtual void* GetHandlerPtr() const { return NULL;/*(void*)m_pHandler;*/ } protected: TOBJECT* m_pObject; Handler m_pHandler; }; class Event { public: Event(void) { } ~Event(void) { for (std::vector<IHandler*>::iterator it = m_rgpHandler.begin(); it != m_rgpHandler.end(); ++it) { delete *it; *it = NULL; } } void AddHandler(IHandler* pHandler) { if (std::find(m_rgpHandler.begin(), m_rgpHandler.end(), pHandler) != m_rgpHandler.end()) { return; } m_rgpHandler.push_back(pHandler); } void RemvoeHandler(IHandler* pHandler) { } IHandler* FindHandler(void* pMemFunc, void* pObject) { for (std::vector<IHandler*>::iterator it = m_rgpHandler.begin(); it != m_rgpHandler.end(); ++it) { if ((*it)->GetObjectPtr() == pObject && (*it)->GetHandlerPtr() == pMemFunc) return *it; } return NULL; } void operator()(int wParam, int lParam) { for (std::vector<IHandler*>::iterator it = m_rgpHandler.begin(); it != m_rgpHandler.end(); ++it) { (*it)->Call(wParam, lParam); } } protected: std::vector<IHandler*> m_rgpHandler; }; template<typename THANDLER, typename TOBJECT> void SetWatch(Event& evt, THANDLER pHandler, TOBJECT* pObject) { MemHandler<TOBJECT>* pEventHandler = new MemHandler<TOBJECT>; pEventHandler->SetHandler(reinterpret_cast<MemHandler<TOBJECT>::Handler>(pHandler)); pEventHandler->SetObject(pObject); evt.AddHandler(pEventHandler); }
上面的代码的委托只支持两个参数的成员函数,而且这两个参数必须是int wParam, int lParam,如果想实现更为复杂的委托,推荐看Andrei Alexandrescu写的《C++设计新思维:泛型编程与设计模式之应用》(侯捷 於春景 译),里面有非常详细且精彩的描述。
浙公网安备 33010602011771号