首页 > 代码库 > C++学习笔记38:事件机制
C++学习笔记38:事件机制
事件基本概念
- 操作系统或应用程序内部发生某件事,程序的某个组件需要响应该事件,并进行特定处理
面向对象架构中,事件响应函数最可能为成员函数
- 问题:指向类成员函数的指针不能转换为哑型指针void *,也不能随意转换为指向另一个类的成员函数的指针
- 解决方案:使用指向指向类成员函数的指针的指针
实现策略:事件委托模型
- Event类模板:管理事件响应者对象,实现事件多播
- EventResponsor类模板:响应者对象与响应者行为配对
- Empty类:委托模型和指针转换
#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; typeder 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: EventResponsor _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 =http://www.mamicode.com/= 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, viod *tag) { cout << reinterpret_cast<char *>(tag) << value << "." << endl; } }; int main() { const char *s = "Now the value is"; Trigger t; Actor a1, 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; }
C++学习笔记38:事件机制
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。