您的位置:首页 > 编程语言 > C语言/C++

C++代理实现

2015-06-13 16:25 302 查看
//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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: