C++ 事件机制实现
来源:互联网 发布:专业电子相册制作软件 编辑:程序博客网 时间:2024/06/05 18:34
C++ 事件机制实现
分类: win32 SDK 2011-05-18 16:19 40人阅读 评论(0)收藏 举报
http://www.cppblog.com/zhuweisky/archive/2005/09/11/193.html
事件是面向组件开发的必要特性之一,但C++不直接支持事件,没关系,我自己实现了一个,感觉很好用,分享给大家!
最开始打算用函数指针模拟事件,但由于C++中成员函数指针不能和void*相互强转,而且 typedef中不能含有模板,所以才不得已以接口继承实现。这样效果也不错 :)
一. 先看看事件接口定义和实现
- #ifndef IEVENT_H
- #define IEVENT_H
- /*
- 以下各基础设施是在C++中事件机制的完整实现,事件是面向组件开发的必要特性之一。
- 创 作 者:sky
- 时 间:2005.06.22
- 修订时间:2005.06.22
- */
- #include "../Collection/SafeArrayList.h"
- template<class SenderType ,class ParaType> class EventPublisher ;
- class NullType
- {
- };
- // IEventHandler 是事件处理句柄,预定事件的类从此接口继承以实现事件处理函数
- template<class SenderType ,class ParaType>
- interface IEventHandler
- {
- public:
- virtual ~IEventHandler(){}
- private:
- virtual void HandleEvent(SenderType sender ,ParaType para) = 0 ;
- friend class EventPublisher<SenderType ,ParaType> ;
- };
- // IEvent 事件预定方通过此接口预定事件
- template<class SenderType ,class ParaType>
- interface IEvent
- {
- public:
- virtual ~IEvent(){}
- virtual void Register (IEventHandler<SenderType ,ParaType>* handler) = 0 ;
- virtual void UnRegister(IEventHandler<SenderType ,ParaType>* handler) = 0 ;
- };
- // IEventActivator 事件发布方通过此接口触发事件
- template<class SenderType ,class ParaType>
- interface IEventActivator
- {
- public:
- virtual ~IEventActivator(){}
- virtual void Invoke(SenderType sender ,ParaType para) = 0;
- virtual int HandlerCount() = 0;
- virtual IEventHandler<SenderType ,ParaType>* GetHandler(int index) = 0;
- };
- // IEventPublisher 事件发布方发布事件相当于就是发布一个IEventPublisher派生类的对象
- // 不过仅仅将该对象的IEvent接口发布即可。
- template<class SenderType ,class ParaType>
- interface IEventPublisher : public IEvent<SenderType ,ParaType> ,public IEventActivator<SenderType ,ParaType>
- {
- };
- // EventPublisher是IEventPublisher的默认实现
- template<class SenderType ,class ParaType>
- class EventPublisher :public IEventPublisher<SenderType ,ParaType>
- {
- private:
- SafeArrayList< IEventHandler<SenderType ,ParaType> > handerList ;
- IEventHandler<SenderType ,ParaType>* innerHandler ;
- public:
- void Register(IEventHandler<SenderType ,ParaType>* handler)
- {
- this->handerList.Add(handler) ;
- }
- void UnRegister(IEventHandler<SenderType ,ParaType>* handler)
- {
- this->handerList.Remove(handler) ;
- }
- void Invoke(SenderType sender ,ParaType para)
- {
- int count = this->handerList.Count() ;
- for(int i=0 ;i<count ;i++)
- {
- IEventHandler<SenderType ,ParaType>* handler = this->handerList.GetElement(i) ;
- handler->HandleEvent(sender ,para) ;
- }
- }
- int HandlerCount()
- {
- return this->handerList.Count() ;
- }
- IEventHandler<SenderType ,ParaType>* GetHandler(int index)
- {
- return this->handerList.GetElement(index) ;
- }
- };
- #endif
上面的实现是浅显易懂的,关键是要注意IEventPublisher的双重身份-- 事件发布方最好发布IEvent指针给外部,而该指针实际指向的是一个EventPublisher对象,这是为了避免外部直接调用IEventActivator接口的方法。
二. 一个定时器类Timer,演示如何发布事件。想必大家都知道定时器的用途了哦,这个Timer就像C#中的Timer类一样。
- #ifndef TIMER_H
- #define TIMER_H
- /*
- Timer 定时器,每经过一段指定时间就触发事件
- 创 作 者:sky
- 时 间:2005.06.22
- 修订时间:2005.06.22
- */
- #include "IEvent.h"
- #include "Thread.h"
- void TimerThreadStart(void* para) ;
- class Timer
- {
- private:
- int spanInMillSecs ;
- volatile bool isStop ;
- volatile bool timerThreadDone ;
- public:
- friend void TimerThreadStart(void* para) ;
- IEvent<Timer* ,NullType>* TimerTicked ;
- Timer(int span_InMillSecs)
- {
- this->isStop = true ;
- this->timerThreadDone = true ;
- this->spanInMillSecs = span_InMillSecs ;
- this->TimerTicked = new EventPublisher<Timer* ,NullType> ;
- }
- ~Timer()
- {
- this->Stop() ;
- delete this->TimerTicked ;
- }
- void Start()
- {
- if(! this->isStop)
- {
- return ;
- }
- this->isStop = false ;
- Thread thread ;
- thread.Start(TimerThreadStart ,this) ;
- //unsigned int dwThreadId ;
- //HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0 , (unsigned int (_stdcall*)(void*))&TimerThreadStart , this, 0, &dwThreadId);
- }
- void Stop()
- {
- if( this->isStop)
- {
- return ;
- }
- this->isStop = true ;
- //等待工作线程退出
- while(! this->timerThreadDone)
- {
- Sleep(200) ;
- }
- }
- private:
- void WorkerThread()
- {
- this->timerThreadDone = false ;
- while(! this->isStop)
- {
- Sleep(this->spanInMillSecs) ;
- if(this->isStop)
- {
- break ;
- }
- NullType nullObj ;
- ((EventPublisher<Timer* ,NullType>*)this->TimerTicked)->Invoke(this ,nullObj) ;
- }
- this->timerThreadDone = true ;
- }
- };
- void TimerThreadStart(void* para)
- {
- Timer* timer = (Timer*)para ;
- timer->WorkerThread() ;
- }
- #endif
上面的示例清晰地说明了如何发布一个事件,如何在适当的时候触发事件,接下来看看如何预定事件。
三. 预定事件例子
- class TimerEventExample :public IEventHandler<Timer* ,NullType> ,CriticalSection
- {
- private:
- Timer* timer ;
- public:
- TimerEventExample(int checkSpan)
- {
- this->timer = new Timer(checkSpan) ;
- this->timer->TimerTicked->Register(this) ;
- }
- ~TimerEventExample()
- {
- delete this->timer ;
- }
- private:
- //处理定时事件
- void HandleEvent(Timer* sender ,NullType para)
- {
- cout<<"Time ticked !"<<endl ;
- }
- };
到这里,已经将C++中的事件机制的实现及使用讲清楚了。C#提供了很多便利的基础设施来支持组件开发,而在C++中,这些基础设施需要自己动手来构建,在拥有了这些设施之后,相信使用C++进行组件开发会轻松一点。
- C#事件处理机制
- C# 事件机制
- Unity3D (C#)事件分发机制的实现
- C++ 事件机制实现
- C++ 事件机制实现
- C++实现事件机制
- C++ 事件机制实现
- C++ 事件机制实现
- C++ 事件机制实现
- C++ 事件机制实现
- C++实现事件机制
- C++ 事件机制实现
- C++ 事件机制实现
- C++实现事件机制
- 3.7 event.c:“事件”机制
- 事件机制之C++实现
- lua实现c#事件机制
- ActionScript事件模型实现机制
- 2011-10-19 java servlet开始-http协议。
- 通过同名字符串来调用函数<python>
- 异步消息的传递-回调机制
- windows下如何调用BIOS的函数
- shell脚本入门
- C++ 事件机制实现
- JS获取事件对象,获取事件的源对象(Firefox,IE)
- CPU占用过高解决思路一
- 看美国队长,有感
- 跨域cookie
- 很有爱的输入法BrailleType:让盲人也能打字
- 用PE安装Windows7提示 解决无法创建新的系统分区,也无法定位现有的系统分区
- 为自己准备的书籍,学习之
- 模块的介绍