C++代理实现

//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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值