//Delegate.h
#include <list>
using namespace std;
class CDelegateBase
{
public:
CDelegateBase(void *pObject, void *pFn)
{
m_pObject = pObject;
m_pFn = pFn;
}
CDelegateBase(const CDelegateBase& rhs)
{
m_pObject = rhs.m_pObject;
m_pFn = rhs.m_pFn;
}
virtual ~CDelegateBase(){};
bool Equals(const CDelegateBase& rhs) const
{
return m_pObject == rhs.m_pObject && m_pFn == rhs.m_pFn;
}
bool operator() (void *param)
{
return Invoke(param);
}
virtual CDelegateBase* Copy() = 0;
protected:
void *GetFn(){return m_pFn;}
void *GetObject(){return m_pObject;}
virtual bool Invoke(void *param) = 0;
private:
void *m_pObject;
void *m_pFn;
};
class CDelegateStatic: public CDelegateBase
{
typedef bool (*Fn)(void*);
public:
CDelegateStatic(Fn pFn) : CDelegateBase(NULL, pFn) { }
CDelegateStatic(const CDelegateStatic& rhs) : CDelegateBase(rhs) { }
virtual CDelegateBase* Copy() { return new CDelegateStatic(*this); }
protected:
virtual bool Invoke(void* param)
{
Fn pFn = (Fn)GetFn();
return (*pFn)(param);
}
};
template <class O, class T>
class CDelegate : public CDelegateBase
{
typedef bool (T::* Fn)(void*);
public:
CDelegate(O* pObj, Fn pFn) : CDelegateBase(pObj, &pFn), m_pFn(pFn) { }
CDelegate(const CDelegate& rhs) : CDelegateBase(rhs) { m_pFn = rhs.m_pFn; }
virtual CDelegateBase* Copy() { return new CDelegate(*this); }
protected:
virtual bool Invoke(void* param)
{
O* pObject = (O*) GetObject();
return (pObject->*m_pFn)(param);
}
private:
Fn m_pFn;
};
template <class O, class T>
CDelegate<O, T> MakeDelegate(O* pObject, bool (T::* pFn)(void*))
{
return CDelegate<O, T>(pObject, pFn);
}
inline CDelegateStatic MakeDelegate(bool (*pFn)(void*))
{
return CDelegateStatic(pFn);
}
class CEventSource
{
typedef bool (*FnType)(void*);
public:
~CEventSource()
{
for(list<void *>::iterator iter = m_aDelegates.begin(); iter != m_aDelegates.end(); ++iter){
CDelegateBase* pObject = static_cast<CDelegateBase*>(*iter);
if( pObject) delete pObject;
}
}
operator bool()
{
return m_aDelegates.size()>0;
}
void operator+= (CDelegateBase& d)
{
for(list<void *>::iterator iter = m_aDelegates.begin(); iter != m_aDelegates.end(); ++iter){
CDelegateBase* pObject = static_cast<CDelegateBase*>(*iter);
if( pObject && pObject->Equals(d) ) return;
}
m_aDelegates.push_back(d.Copy());
}
void operator+= (FnType pFn)
{
(*this) += MakeDelegate(pFn);
}
void operator-= (CDelegateBase& d)
{
for(list<void *>::iterator iter = m_aDelegates.begin(); iter != m_aDelegates.end(); ++iter){
CDelegateBase* pObject = static_cast<CDelegateBase*>(*iter);
if( pObject && pObject->Equals(d) ) {
delete pObject;
m_aDelegates.erase(iter);
return;
}
}
}
void operator-= (FnType pFn)
{
(*this) -= MakeDelegate(pFn);
}
bool operator() (void* param)
{
for(list<void *>::iterator iter = m_aDelegates.begin(); iter != m_aDelegates.end(); ++iter){
CDelegateBase* pObject = static_cast<CDelegateBase*>(*iter);
if( pObject && !(*pObject)(param) ) return false;
}
return true;
}
protected:
list<void*> m_aDelegates;
};
使用示例:
#include <stdio.h>
#include "Delegate.h"
bool test1(void *param)
{
printf("hello\n");
return true;
}
class ClsTest
{
public:
bool test(void *param)
{
int a = *(int*)(param);
printf("cls test %d\n", a);
return false;
}
};
int main(void)
{
CEventSource event;
event += test1;
ClsTest cls;
event += MakeDelegate(&cls, &ClsTest::test);
int a = 8;
event((void*)&a);
event -= test1;
event((void*)&a);
getchar();
return 0;
}