基本上是参照
实现基于C++的动态事件机制
的例子,做了一些改进,使之更加像.Net.功能加强,
#include
<
map
>
//
#include<multi_map>
#include
<
iostream
>
#include
<
stdlib.h
>
#include
<
vector
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
using
namespace
std;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
#include"stdafx.h"
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/**
*基类
*/
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
class
TObject
...
{}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/**
*事件参数类
*/
template
<
class
T
>
class
TEventArg:
public
TObject
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
Tvalue;
public:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
TEventArg():value()...{}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
TEventArg(Tx)...{value=x;}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
TEventArg(constTEventArg&ref)...{value=ref;}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
TEventArg<T>&operator=(Tx)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
value=x;
return*this;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
TEventArg<T>&operator=(TEventArg<T>x)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
value=x;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return*this;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
operatorT()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
returnvalue;
}
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/**
*事件类
*/
template
<
class
T
>
class
TEvent:
public
TObject
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*事件句柄类型定义
*/
typedefvoid(TObject::*TEventHandler)(TEventArg<T>[]);
typedefmultimap<TObject*,TEventHandler>TEventMap;;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
private:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*保存事件处理方法的句柄
*通常只要保存一个事件处理方法就可以
*这里是为了演示一个事件上激发多个处理句柄的情况,使用了Multi_Map来
*保存所有句柄
*/
TEventMapm_HandlerMap;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*清除所有事件处理方法的句柄
*/
voidclear()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
m_HandlerMap.clear();
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*移除事件处理方法句柄
*/
voidremove(pair<TObject*,TEventHandler>handler)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
//Rangrang=m_HandlerMap.equal_range(handler.first);
for(TEventMap::iteratori=m_HandlerMap.lower_bound(handler.first);i!=m_HandlerMap.upper_bound(handler.first);)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if(i->second==handler.second)
m_HandlerMap.erase(i++);
else
i++;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*句柄的赋值操作,清空已有的句柄,并用新句柄代替
*@seeadd
*/
TEvent<T>&operator=(pair<TObject*,TEventHandler>handler)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
clear();
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
m_HandlerMap.insert(handler.first,handler.second);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return*this;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*添加事件处理方法句柄,在实际情况中,比operator+=操作简单
*/
voidadd(TObject*object,TEventHandlerhandler)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
m_HandlerMap.insert(make_pair(object,handler));
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*添加事件处理方法句柄
*/
TEvent<T>&operator+=(pair<TObject*,TEventHandler>handler)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
m_HandlerMap.insert(make_pair(handler.first,handler.second));
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return*this;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*删除句柄
*/
TEvent<T>&operator-=(pair<TObject*,TEventHandler>handler)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
remove(handler);
return*this;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
TEvent<T>&operator-=(TObject*object)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
m_HandlerMap.erase(object);
return*this;
}
TEvent<T>&operator-=(TObject&refObject)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
m_HandlerMap.erase(&refObject);
return*this;
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*激发事件
*/
voidfire(TEventArg<T>args[])
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*循环激发所有事件
*/
for(TEventMap::const_iteratori=m_HandlerMap.begin();i!=m_HandlerMap.end();++i)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if(i->second!=NULL)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
TObject*object=(*i).first;
TEventHandlerhandler=(*i).second;
(object->*handler)(args);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
}
}//methodfire
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/**
*事件的激发源
*/
template
<
class
T
>
class
TMyEventFirer:
public
TObject
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**////事件
TEvent<T>MyEvent;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**////某个将会激发事件的方法
voidfireEvent(TEventArg<T>args[])
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
MyEvent.fire(args);
}
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/**
*处理事件的对象之一
*/
class
A:
public
TObject
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
A()...{}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*事件处理方法
*/
voidfunc(TEventArg<int>args[])
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
std::cout<<"A:func:"<<(int)args[0]<<std::endl;
}
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/**
*处理事件的对象之二
*/
class
B:
public
TObject
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
B()...{}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//**
*事件处理方法
*/
voidfunc(TEventArg<int>args[])
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
cout<<"B:func:"<<(int)args[0]<<endl;
}
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main(
int
argc,
char
*
argv[])
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
TMyEventFirer<int>firer;//事件源
Aa;//事件处理对象
Bb;//事件处理对象
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//添加A对象的事件处理
firer.MyEvent+=make_pair<TObject*,TEvent<int>::TEventHandler>(&a,static_cast<TEvent<int>::TEventHandler>(&A::func));
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//添加B对象的事件处理
firer.MyEvent+=make_pair<TObject*,TEvent<int>::TEventHandler>(&b,static_cast<TEvent<int>::TEventHandler>(&B::func));
firer.MyEvent+=make_pair<TObject*,TEvent<int>::TEventHandler>(&b,static_cast<TEvent<int>::TEventHandler>(&B::func));
firer.MyEvent+=make_pair<TObject*,TEvent<int>::TEventHandler>(&b,static_cast<TEvent<int>::TEventHandler>(&B::func));
firer.MyEvent+=make_pair<TObject*,TEvent<int>::TEventHandler>(&b,static_cast<TEvent<int>::TEventHandler>(&B::func));
firer.MyEvent-=make_pair<TObject*,TEvent<int>::TEventHandler>(&b,static_cast<TEvent<int>::TEventHandler>(&B::func));
//再次添加A对象的事件处理
//由于没有判别唯一性,所以A对象的事件处理会被激发次
firer.MyEvent.add(&a,static_cast<TEvent<int>::TEventHandler>(&A::func));
//firer.MyEvent-=b;
//准备参数
TEventArg<int>args[1];
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//初始化
args[0]=999;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//激发事件
firer.fireEvent(args);
system("pause");
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return0;
}
相比较原来版本,最大的改动是保存事件处理方法的容器从数组改成了multi_map.
typedef multimap<TObject*, TEventHandler > TEventMap;
改动的目的是,实现一次性注销指定侦听对象的所有注册事件,以及避免原理方案中同一侦听者同一个事件被注册多次就触发多次的问题.