C++实现代理(delegate)

记不清出处了,实现代码是别人的,自己整理的

//delegate.h

/*!
@file
@author		Albert Semenov
@date		11/2007
@module
*/
/*
This file is part of MyGUI.

MyGUI is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MyGUI is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __DELEGATE_H__
#define __DELEGATE_H__

#include <typeinfo>
#include <list>

namespace delegates
{
	// base class for classes that want to detach themselves from the multi delegates
	class IDelegateUnlink
	{
	public:
		virtual ~IDelegateUnlink() { }

		IDelegateUnlink() { m_baseDelegateUnlink = this; }
		bool compare(IDelegateUnlink * _unlink) const { return m_baseDelegateUnlink == _unlink->m_baseDelegateUnlink; }

	private:
		IDelegateUnlink * m_baseDelegateUnlink;
	};

	inline IDelegateUnlink * GetDelegateUnlink(void * _base) { return 0; }
	inline IDelegateUnlink * GetDelegateUnlink(IDelegateUnlink * _base) { return _base; }
}

// Generation Number of delegates to the various parameters

// no parameters
#define DELEGATE_SUFFIX       0
#define DELEGATE_TEMPLATE
#define DELEGATE_TEMPLATE_PARAMS
#define DELEGATE_TEMPLATE_ARGS
#define DELEGATE_T_TEMPLATE_PARAMS  <typename T>
#define DELEGATE_T_TEMPLATE_ARGS <T>
#define DELEGATE_PARAMS
#define DELEGATE_ARGS
#define DELEGATE_TYPENAME

#include "delegate_imp.h"

// one parameter
#define DELEGATE_SUFFIX       1
#define DELEGATE_TEMPLATE	template
#define DELEGATE_TEMPLATE_PARAMS  <typename TP1>
#define DELEGATE_TEMPLATE_ARGS    <TP1>
#define DELEGATE_T_TEMPLATE_PARAMS  <typename T, typename TP1>
#define DELEGATE_T_TEMPLATE_ARGS    <T, TP1>
#define DELEGATE_PARAMS       TP1 p1
#define DELEGATE_ARGS         p1
#define DELEGATE_TYPENAME     typename

#include "delegate_imp.h"

// two parameters
#define DELEGATE_SUFFIX       2
#define DELEGATE_TEMPLATE	template
#define DELEGATE_TEMPLATE_PARAMS  <typename TP1, typename TP2>
#define DELEGATE_TEMPLATE_ARGS    <TP1, TP2>
#define DELEGATE_T_TEMPLATE_PARAMS  <typename T, typename TP1, typename TP2>
#define DELEGATE_T_TEMPLATE_ARGS    <T, TP1, TP2>
#define DELEGATE_PARAMS       TP1 p1, TP2 p2
#define DELEGATE_ARGS         p1, p2
#define DELEGATE_TYPENAME     typename

#include "delegate_imp.h"

// three parameters
#define DELEGATE_SUFFIX       3
#define DELEGATE_TEMPLATE	template
#define DELEGATE_TEMPLATE_PARAMS  <typename TP1, typename TP2, typename TP3>
#define DELEGATE_TEMPLATE_ARGS    <TP1, TP2, TP3>
#define DELEGATE_T_TEMPLATE_PARAMS  <typename T, typename TP1, typename TP2, typename TP3>
#define DELEGATE_T_TEMPLATE_ARGS    <T, TP1, TP2, TP3>
#define DELEGATE_PARAMS       TP1 p1, TP2 p2, TP3 p3
#define DELEGATE_ARGS         p1, p2, p3
#define DELEGATE_TYPENAME     typename

#include "delegate_imp.h"

// four parameters
#define DELEGATE_SUFFIX       4
#define DELEGATE_TEMPLATE	template
#define DELEGATE_TEMPLATE_PARAMS  <typename TP1, typename TP2, typename TP3, typename TP4>
#define DELEGATE_TEMPLATE_ARGS    <TP1, TP2, TP3, TP4>
#define DELEGATE_T_TEMPLATE_PARAMS  <typename T, typename TP1, typename TP2, typename TP3, typename TP4>
#define DELEGATE_T_TEMPLATE_ARGS    <T, TP1, TP2, TP3, TP4>
#define DELEGATE_PARAMS       TP1 p1, TP2 p2, TP3 p3, TP4 p4
#define DELEGATE_ARGS         p1, p2, p3, p4
#define DELEGATE_TYPENAME     typename

#include "delegate_imp.h"

// five parameters
#define DELEGATE_SUFFIX       5
#define DELEGATE_TEMPLATE	template
#define DELEGATE_TEMPLATE_PARAMS  <typename TP1, typename TP2, typename TP3, typename TP4, typename TP5>
#define DELEGATE_TEMPLATE_ARGS    <TP1, TP2, TP3, TP4, TP5>
#define DELEGATE_T_TEMPLATE_PARAMS  <typename T, typename TP1, typename TP2, typename TP3, typename TP4, typename TP5>
#define DELEGATE_T_TEMPLATE_ARGS    <T, TP1, TP2, TP3, TP4, TP5>
#define DELEGATE_PARAMS       TP1 p1, TP2 p2, TP3 p3, TP4 p4, TP5 p5
#define DELEGATE_ARGS         p1, p2, p3, p4, p5
#define DELEGATE_TYPENAME     typename

#include "delegate_imp.h"

#endif // __DELEGATE_H__


//delegate_imp.h

/*!
@file
@author		Albert Semenov
@date		11/2007
@module
*/
/*
This file is part of MyGUI.

MyGUI is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MyGUI is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
*/

namespace delegates
{

#define MYGUI_COMBINE(a, b)						MYGUI_COMBINE1(a, b)
#define MYGUI_COMBINE1(a, b)					a##b

#define MYGUI_I_DELEGATE						MYGUI_COMBINE(IDelegate, DELEGATE_SUFFIX)

#define MYGUI_C_STATIC_DELEGATE					MYGUI_COMBINE(CStaticDelegate, DELEGATE_SUFFIX)
#define MYGUI_C_METHOD_DELEGATE					MYGUI_COMBINE(CMethodDelegate, DELEGATE_SUFFIX)

#define MYGUI_C_DELEGATE						MYGUI_COMBINE(CDelegate, DELEGATE_SUFFIX)
#define MYGUI_C_MULTI_DELEGATE					MYGUI_COMBINE(CMultiDelegate, DELEGATE_SUFFIX)


	// base class of all delegates
	DELEGATE_TEMPLATE   DELEGATE_TEMPLATE_PARAMS
	class MYGUI_I_DELEGATE
	{
	public:
		virtual ~MYGUI_I_DELEGATE() { }
		virtual bool isType(const std::type_info& _type) = 0;
		virtual void invoke(DELEGATE_PARAMS) = 0;
		virtual bool compare(MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS  * _delegate) const = 0;
		virtual bool compare(IDelegateUnlink * _unlink) const { return false; }
	};


	// delegate to a static function
	DELEGATE_TEMPLATE   DELEGATE_TEMPLATE_PARAMS
	class MYGUI_C_STATIC_DELEGATE : public  MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS
	{
	public:
		typedef void(*Func)(DELEGATE_PARAMS);

		MYGUI_C_STATIC_DELEGATE(Func _func) : mFunc(_func) { }

		virtual bool isType(const std::type_info& _type) { return typeid(MYGUI_C_STATIC_DELEGATE DELEGATE_TEMPLATE_ARGS) == _type; }

		virtual void invoke(DELEGATE_PARAMS)
		{
			mFunc(DELEGATE_ARGS);
		}

		virtual bool compare(MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS  * _delegate) const
		{
			if (0 == _delegate || !_delegate->isType(typeid(MYGUI_C_STATIC_DELEGATE DELEGATE_TEMPLATE_ARGS))) return false;
			MYGUI_C_STATIC_DELEGATE DELEGATE_TEMPLATE_ARGS * cast = static_cast<MYGUI_C_STATIC_DELEGATE DELEGATE_TEMPLATE_ARGS *>(_delegate);
			return cast->mFunc == mFunc;
		}
		virtual bool compare(IDelegateUnlink * _unlink) const { return false; }

	private:
		Func mFunc;
	};


	// delegate for the method of the class
	template DELEGATE_T_TEMPLATE_PARAMS
	class MYGUI_C_METHOD_DELEGATE : public  MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS
	{
	public:
		typedef void (T::*Method)(DELEGATE_PARAMS);

		MYGUI_C_METHOD_DELEGATE(IDelegateUnlink * _unlink, T * _object, Method _method) : mUnlink(_unlink), mObject(_object), mMethod(_method) { }

		virtual bool isType(const std::type_info& _type) { return typeid(MYGUI_C_METHOD_DELEGATE DELEGATE_T_TEMPLATE_ARGS) == _type; }

		virtual void invoke(DELEGATE_PARAMS)
		{
			(mObject->*mMethod)(DELEGATE_ARGS);
		}

		virtual bool compare(MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS  * _delegate) const
		{
			if (0 == _delegate || !_delegate->isType(typeid(MYGUI_C_METHOD_DELEGATE DELEGATE_T_TEMPLATE_ARGS))) return false;
			MYGUI_C_METHOD_DELEGATE DELEGATE_T_TEMPLATE_ARGS  * cast = static_cast<MYGUI_C_METHOD_DELEGATE DELEGATE_T_TEMPLATE_ARGS  *>(_delegate);
			return cast->mObject == mObject && cast->mMethod == mMethod;
		}

		virtual bool compare(IDelegateUnlink * _unlink) const
		{
			return mUnlink == _unlink;
		}

	private:
		IDelegateUnlink *mUnlink;
		T * mObject;
		Method mMethod;
	};

} // namespace delegates

// template to create a delegate static function
// parameters: a pointer to a function
// example : newDelegate(funk_name);
// example : newDelegate(class_name::static_method_name);
DELEGATE_TEMPLATE   DELEGATE_TEMPLATE_PARAMS
inline  delegates::MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS  * newDelegate(void(*_func)(DELEGATE_PARAMS))
{
	return new delegates::MYGUI_C_STATIC_DELEGATE DELEGATE_TEMPLATE_ARGS(_func);
}


// template to create a delegate class method
// options : pointer to the class object and a pointer to a class method
// example : newDelegate(&object_name, &class_name::method_name);
template DELEGATE_T_TEMPLATE_PARAMS
inline  delegates::MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS  * newDelegate(T * _object, void (T::*_method)(DELEGATE_PARAMS))
{
	return new delegates::MYGUI_C_METHOD_DELEGATE  DELEGATE_T_TEMPLATE_ARGS(delegates::GetDelegateUnlink(_object), _object, _method);
}

namespace delegates
{
	// pattern of the delegate class
	DELEGATE_TEMPLATE   DELEGATE_TEMPLATE_PARAMS
	class MYGUI_C_DELEGATE
	{
	public:
		typedef  MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS  IDelegate;

		MYGUI_C_DELEGATE() : mDelegate(0) { }
		MYGUI_C_DELEGATE(const MYGUI_C_DELEGATE  DELEGATE_TEMPLATE_ARGS& _event)
		{
			// pick up his own
			mDelegate = _event.mDelegate;
			const_cast<MYGUI_C_DELEGATE  DELEGATE_TEMPLATE_ARGS&>(_event).mDelegate = 0;
		}
		~MYGUI_C_DELEGATE() { clear(); }

		bool empty() const { return mDelegate == 0; }

		void clear()
		{
			if (mDelegate)
			{
				delete mDelegate;
				mDelegate = 0;
			}
		}

		MYGUI_C_DELEGATE  DELEGATE_TEMPLATE_ARGS & operator=(IDelegate* _delegate)
		{
			delete mDelegate;
			mDelegate = _delegate;
			return *this;
		}

		MYGUI_C_DELEGATE  DELEGATE_TEMPLATE_ARGS & operator=(const MYGUI_C_DELEGATE  DELEGATE_TEMPLATE_ARGS& _event)
		{
			// pick up his own
			delete mDelegate;
			mDelegate = _event.mDelegate;
			const_cast<MYGUI_C_DELEGATE  DELEGATE_TEMPLATE_ARGS&>(_event).mDelegate = 0;

			return *this;
		}

		void operator()(DELEGATE_PARAMS)
		{
			if (mDelegate == 0) return;
			mDelegate->invoke(DELEGATE_ARGS);
		}

	private:
		IDelegate * mDelegate;
	};


	// template class multi delegate
	DELEGATE_TEMPLATE   DELEGATE_TEMPLATE_PARAMS
	class MYGUI_C_MULTI_DELEGATE
	{
	public:
		typedef  MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS  IDelegate;
		typedef DELEGATE_TYPENAME std::list<IDelegate* /*, Allocator<IDelegate*>*/ > ListDelegate;
		typedef DELEGATE_TYPENAME ListDelegate::iterator ListDelegateIterator;
		typedef DELEGATE_TYPENAME ListDelegate::const_iterator ConstListDelegateIterator;

		MYGUI_C_MULTI_DELEGATE() { }
		~MYGUI_C_MULTI_DELEGATE() { clear(); }

		bool empty() const
		{
			for (ConstListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
			{
				if (*iter) return false;
			}
			return true;
		}

		void clear()
		{
			for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
			{
				if (*iter)
				{
					delete (*iter);
					(*iter) = 0;
				}
			}
		}

		void clear(IDelegateUnlink * _unlink)
		{
			for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
			{
				if ((*iter) && (*iter)->compare(_unlink))
				{
					delete (*iter);
					(*iter) = 0;
				}
			}
		}

		MYGUI_C_MULTI_DELEGATE  DELEGATE_TEMPLATE_ARGS & operator+=(IDelegate* _delegate)
		{
			for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
			{
				if ((*iter) && (*iter)->compare(_delegate))
				{
					delete _delegate;
					return *this;
					//MYGUI_ASSERT(false, "dublicate delegate");
				}
			}
			mListDelegates.push_back(_delegate);
			return *this;
		}

		MYGUI_C_MULTI_DELEGATE  DELEGATE_TEMPLATE_ARGS & operator-=(IDelegate* _delegate)
		{
			for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
			{
				if ((*iter) && (*iter)->compare(_delegate))
				{
					// verify the identity of the delegates
					if ((*iter) != _delegate) delete (*iter);
					(*iter) = 0;
					break;
				}
			}
			delete _delegate;
			return *this;
		}

		void operator()(DELEGATE_PARAMS)
		{
			ListDelegateIterator iter = mListDelegates.begin();
			while (iter != mListDelegates.end())
			{
				if (0 == (*iter))
				{
					iter = mListDelegates.erase(iter);
				}
				else
				{
					(*iter)->invoke(DELEGATE_ARGS);
					++iter;
				}
			}
		}

	private:
		// constructor and operator =, without implementation, just for private
		MYGUI_C_MULTI_DELEGATE(const MYGUI_C_MULTI_DELEGATE  DELEGATE_TEMPLATE_ARGS & _event);
		MYGUI_C_MULTI_DELEGATE  DELEGATE_TEMPLATE_ARGS & operator=(const MYGUI_C_MULTI_DELEGATE  DELEGATE_TEMPLATE_ARGS & _event);


	private:
		ListDelegate mListDelegates;

	};


#undef MYGUI_COMBINE
#undef MYGUI_COMBINE1

#undef MYGUI_I_DELEGATE

#undef MYGUI_C_STATIC_DELEGATE
#undef MYGUI_C_METHOD_DELEGATE

#undef MYGUI_C_DELEGATE
#undef MYGUI_C_MULTI_DELEGATE

#undef DELEGATE_SUFFIX
#undef DELEGATE_TEMPLATE
#undef DELEGATE_TEMPLATE_PARAMS
#undef DELEGATE_TEMPLATE_ARGS
#undef DELEGATE_T_TEMPLATE_PARAMS
#undef DELEGATE_T_TEMPLATE_ARGS
#undef DELEGATE_PARAMS
#undef DELEGATE_ARGS
#undef DELEGATE_TYPENAME

} // namespace delegates


用法:

#ifndef _OBSERVER_H_
#define _OBSERVER_H_
#include <QVector>
#include <QString>
#include <vector>
#include <iostream>

#include "delegate.h"

using namespace std;

class Observer;

/*主题基类*/
class Subject
{
public:
	virtual void SetSujectState( string status)
	{
		subjectState = status;
	}

	virtual string GetSujectState()
	{
		return subjectState;
	}
	virtual void Notify(){};
protected:
	string subjectState;
};

/*具体主题类*/
class ConcreteSubject : public Subject
{
public:
	ConcreteSubject()
	{

	}

private:
	
};

/*观察者基类*/
class Observer
{
public:
	virtual void Update(){};
};

/*具体观察者*/
class ConcreteObserver : public Observer
{
public:
	ConcreteObserver(ConcreteSubject* pSubject, string name)
	{
		m_psubject = pSubject;
		m_name = name;
	}
	void SetSubject(ConcreteSubject* pSubject)
	{
		m_psubject = pSubject;
	}

	ConcreteSubject* GetSubject( )
	{
		return m_psubject;
	}

	virtual void Update()
	{
		observerState = m_psubject->GetSujectState();
		cout << "观察者:"<<m_name<<"知道,主题的状态为:" <<observerState<< endl;
	}
private:
	string m_name;
	string observerState;
	ConcreteSubject* m_psubject;
};

class StockObserver
{
private:
	string m_name;
	Subject* m_pSubject; //主题通知者
public:
	StockObserver( string name, Subject* pSubject)
	{
		this->m_name = name;
		this->m_pSubject = pSubject;
	}

	//关闭股票行情
	void CloseStockMarket()
	{
		
		cout << m_name << "关闭股票行情软件" << endl;
	}

	void OpenStockMarket()
	{
		cout << m_name << "打开股票行情软件" << endl;
	}
};

class NBAObserver
{
public:
	NBAObserver( string name, Subject* psub)
	{
		this->m_name = name;
		this->m_pSubject = psub;
	}

	void CloseNBADirectSending()
	{
		cout << m_name << "关闭NBA直播,继续工作" << endl;
	}

	void OpenNBADirectSending()
	{
		cout << m_name << "停止工作,打开NBA直播" << endl;
	}
private:
	string m_name;
	Subject* m_pSubject;
};

class Boss : public Subject
{
	typedef delegates::CMultiDelegate0 EvenetHandler;

	typedef delegates::CMultiDelegate1< int> EventHandler1;
public:
	EvenetHandler event; // 委托事件
	EvenetHandler event2; 

	EventHandler1 event3;

	void Notify()
	{
		if (subjectState == "我回来了")
		{
			event();
		}
		else if (subjectState == "我出去了")
		{
			event2();
		}
	}

};
#endif

#include <QtCore/QCoreApplication>
#include "Observer.h"
int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);

	Boss* huhansan = new Boss();

	StockObserver* tongshi1 = new StockObserver(string("aa"), huhansan);
	NBAObserver* tongshi2 = new NBAObserver(string("bb"),huhansan);

	huhansan->event += newDelegate( tongshi1, &StockObserver::CloseStockMarket );
	huhansan->event += newDelegate( tongshi2, &NBAObserver::CloseNBADirectSending);

	huhansan->event2 += newDelegate( tongshi1, &StockObserver::OpenStockMarket);
	huhansan->event2 += newDelegate( tongshi2, &NBAObserver::OpenNBADirectSending);

	string inputstatus;
	while (cin >> inputstatus, inputstatus != "quit")
	{
		huhansan->SetSujectState( inputstatus );
		huhansan->Notify();

		//huhansan->event2.clear( tongshi1);
	}

	return a.exec();
}




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值