zoukankan      html  css  js  c++  java
  • 分享一个C++消费者模式示例代码

    生产消费者应该是一个非常容易使用的设计模式,这个是我在一个网络教材上看到的一个示例代码,使用了模板和聚合,我转载分享下,源代码如下:

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    //空类,用于指代响应者对象
    class Empty {};
    
    
    //事件响应者类模板,保存特定事件的响应者与响应行为
    template< typename EventAction >  class EventResponsor
    {
    public:
    	EventResponsor() : actor(NULL), action(NULL) {  }
    	EventResponsor(Empty * actor, EventAction * action) : actor(actor), action(action) {  }
    	friend  bool operator==(const EventResponsor & lhs, const EventResponsor & rhs)
    	{
    		return lhs.actor == rhs.actor && *lhs.action == *rhs.action;
    	}
    public:    //  公开的数据成员,以方便使用者
    	Empty * actor;
    	EventAction * action;
    };    //template<typename EventAction> class EventResponsor
    
    
    //事件类模板,用于管理特定事件的所有响应者
    template< typename EventAction >  class Event
    {
    public:
    	typedef vector<EventResponsor<EventAction>> EventResponsors;
    	typedef typename vector<EventResponsor<EventAction>>::iterator EventIterator;
    
    public:
    	virtual ~Event()
    	{
    		for (EventIterator it = this->_ers.begin(); it != this->_ers.end(); ++it)
    		{
    			delete it->action, it->action = NULL;
    		}
    	}
    
    	EventResponsors & GetResponsors() { return this->_ers; }
    	//事件绑定,将实际响应者和响应行为挂接到事件响应者对象上
    	template< typename Responsor, typename Action >
    	void Bind(Responsor * actor, Action action)
    	{
    		Action * act = new Action(action);
    		EventResponsor<EventAction> er((Empty*)actor, (EventAction*)act);
    		bool unbound = true;
    		for (EventIterator it = this->_ers.begin(); it != this->_ers.end(); ++it)
    		{
    			if (*it == er)    //  发现重复的事件响应者,说明已绑定
    			{
    				unbound = false;  break;
    			}
    		}
    		if (unbound)
    			this->_ers.push_back(er);
    		else
    			delete er.action, er.action = NULL;
    	}
    	//解除事件绑定,删除事件响应者对象
    	template< typename Responsor, typename Action >
    	void Unbind(Responsor * actor, Action action)
    	{
    		Action * act = new Action(action);
    		EventResponsor<EventAction> er((Empty*)actor, (EventAction*)act);
    		for (EventIterator it = this->_ers.begin(); it != this->_ers.end(); ++it)
    		{
    			if (*it == er)    //  找到待删除的事件响应者对象
    			{
    				delete it->action, this->_ers.erase(it);  break;
    			}
    		}
    		delete er.action, er.action = NULL;
    	}
    
    private:
    	EventResponsors _ers;
    };    //  template<typename EventAction> class Event
    
    			//  定义事件委托模型、指向类成员函数的指针
    typedef  Empty  EventDelegator;
    typedef  void (EventDelegator::*ValueChanged)(int value, void * tag);
    
    //  触发者
    class Trigger
    {
    public:
    	Trigger() : _value(0) {  }
    	void SetValue(int value, void * tag);
    	int GetValue() { return _value; }
    public:
    	//  值变化事件,公开属性,方便在类外设定
    	Event<ValueChanged>  value_changed;
    private:
    	int  _value;
    };
    
    //  设定值,遍历特定事件的响应对象列表,逐一触发值变更事件
    void  Trigger::SetValue(int value, void * tag)
    {
    	if (_value == value)
    		return;
    	_value = value;
    	Event<ValueChanged>::EventResponsors  ers;
    	ers = this->value_changed.GetResponsors();
    	if (!ers.empty())
    	{
    		Event<ValueChanged>::EventIterator  it;
    		for (it = ers.begin(); it != ers.end(); ++it)
    		{
    			((it->actor)->*(*(it->action)))(value, tag);    //  响应事件
    		}
    	}
    }
    //  行动者
    class Actor
    {
    public:
    	//  侦听事件,绑定本对象的事件响应函数到侦听的事件
    	void  Listen(Trigger * trigger)
    	{
    		trigger->value_changed.Bind(this, &Actor::OnValueChanged);
    	}
    
    	//  停止侦听,从侦听的事件中取消绑定本对象的事件响应活动
    	void  Unlisten(Trigger * trigger)
    	{
    		trigger->value_changed.Unbind(this, &Actor::OnValueChanged);
    	}
    
    	//  值变更事件的响应函数
    	void  OnValueChanged(int value, void * tag)
    	{
    		cout << reinterpret_cast<char*>(tag) << value << "." << endl;
    	}
    };
    
    class Actor1
    {
    public:
    	//  侦听事件,绑定本对象的事件响应函数到侦听的事件
    	void  Listen(Trigger * trigger)
    	{
    		trigger->value_changed.Bind(this, &Actor1::OnValueChanged1);
    	}
    
    	//  停止侦听,从侦听的事件中取消绑定本对象的事件响应活动
    	void  Unlisten(Trigger * trigger)
    	{
    		trigger->value_changed.Unbind(this, &Actor1::OnValueChanged1);
    	}
    
    	//  值变更事件的响应函数
    	void  OnValueChanged1(int value, void * tag)
    	{
    		cout << reinterpret_cast<char*>(tag) << value << "." << endl;
    	}
    };
    
    int main()
    {	
    	const char* s = "Now the value is ";
    	Trigger  t;
    	Actor  a1;
    	Actor1 a2;
    
    	a1.Listen(&t);
    	a2.Listen(&t);
    
    	cout << "Listening..." << endl;
    	t.SetValue(10, reinterpret_cast<void*>(const_cast<char*>(s)));
    
    	a2.Unlisten(&t);
    	cout << "Listening again..." << endl;
    	t.SetValue(20, reinterpret_cast<void*>(const_cast<char*>(s)));
    
    	return 0;
    }
    

      

  • 相关阅读:
    ALinq Dynamic 使用指南——前言
    前端与后端分离的架构实例(三)
    前端与后端分离的架构实例(二)
    启动画面QSplashScreen鼠标点击的时候不退出
    Qt组件屏蔽鼠标激活
    Qt LNK2001错误
    QtDesigner中设定一个组件位于另一个组件上方
    QToolButton设置图片
    osgearth_package切片工具切局部影像或者高程tif无法生成切片问题;切完数据集无法显示问题
    Qt输入框添加搜索按钮,以及自动补全内容
  • 原文地址:https://www.cnblogs.com/prophet-ss/p/8713661.html
Copyright © 2011-2022 走看看