一个用C++模拟.Net事件机制的封装

基本上是参照

实现基于C++的动态事件机制

的例子,做了一些改进,使之更加像.Net.功能加强,


#include
< map >
// #include<multi_map>
#include < iostream >
#include
< stdlib.h >
#include
< vector >

using namespace std;


// #include"stdafx.h"

/**/ /**
*基类
*/

class TObject ... {} ;

/**/ /**
*事件参数类
*/

template
< class T >
class TEventArg: public TObject
... {
Tvalue;
public:
TEventArg():value()
...{}

TEventArg(Tx)
...{value=x;}

TEventArg(
constTEventArg&ref)...{value=ref;}

TEventArg
<T>&operator=(Tx)
...{
value
=x;
return*this;
}


TEventArg
<T>&operator=(TEventArg<T>x)
...{
value
=x;

return*this;
}


operatorT()
...{
returnvalue;
}

}
;


/**/ /**
*事件类
*/

template
< class T >
class TEvent: public TObject
... {
public:
/**//**
*事件句柄类型定义
*/

typedef
void(TObject::*TEventHandler)(TEventArg<T>[]);
typedefmultimap
<TObject*,TEventHandler>TEventMap;;


private:
/**//**
*保存事件处理方法的句柄
*通常只要保存一个事件处理方法就可以
*这里是为了演示一个事件上激发多个处理句柄的情况,使用了Multi_Map来
*保存所有句柄
*/

TEventMapm_HandlerMap;


public:
/**//**
*清除所有事件处理方法的句柄
*/

voidclear()
...{
m_HandlerMap.clear();
}


/**//**
*移除事件处理方法句柄
*/

voidremove(pair<TObject*,TEventHandler>handler)
...{
//Rangrang=m_HandlerMap.equal_range(handler.first);
for(TEventMap::iteratori=m_HandlerMap.lower_bound(handler.first);i!=m_HandlerMap.upper_bound(handler.first);)
...{
if(i->second==handler.second)
m_HandlerMap.erase(i
++);
else
i
++;
}


}


/**//**
*句柄的赋值操作,清空已有的句柄,并用新句柄代替
*@seeadd
*/

TEvent
<T>&operator=(pair<TObject*,TEventHandler>handler)
...{
clear();

m_HandlerMap.insert(handler.first,handler.second);

return*this;
}


/**//**
*添加事件处理方法句柄,在实际情况中,比operator+=操作简单
*/

voidadd(TObject*object,TEventHandlerhandler)
...{
m_HandlerMap.insert(make_pair(
object,handler));

}


/**//**
*添加事件处理方法句柄
*/

TEvent
<T>&operator+=(pair<TObject*,TEventHandler>handler)
...{
m_HandlerMap.insert(make_pair(handler.first,handler.second));

return*this;
}


/**//**
*删除句柄
*/

TEvent
<T>&operator-=(pair<TObject*,TEventHandler>handler)
...{
remove(handler);
return*this;
}


TEvent
<T>&operator-=(TObject*object)
...{
m_HandlerMap.erase(
object);
return*this;
}

TEvent
<T>&operator-=(TObject&refObject)
...{
m_HandlerMap.erase(
&refObject);
return*this;
}

/**//**
*激发事件
*/

voidfire(TEventArg<T>args[])
...{
/**//**
*循环激发所有事件
*/

for(TEventMap::const_iteratori=m_HandlerMap.begin();i!=m_HandlerMap.end();++i)
...{
if(i->second!=NULL)
...{
TObject
*object=(*i).first;
TEventHandlerhandler
=(*i).second;
(
object->*handler)(args);

}

}

}
//methodfire
}
;

/**/ /**
*事件的激发源
*/

template
< class T >
class TMyEventFirer: public TObject
... {
public:
/**////事件
TEvent<T>MyEvent;

/**////某个将会激发事件的方法
voidfireEvent(TEventArg<T>args[])
...{
MyEvent.fire(args);
}

}
;

/**/ /**
*处理事件的对象之一
*/

class A: public TObject
... {
public:
A()
...{}

public:
/**//**
*事件处理方法
*/

voidfunc(TEventArg<int>args[])
...{
std::cout
<<"A:func:"<<(int)args[0]<<std::endl;
}

}
;

/**/ /**
*处理事件的对象之二
*/

class B: public TObject
... {
public:
B()
...{}

public:
/**//**
*事件处理方法
*/

voidfunc(TEventArg<int>args[])
...{
cout
<<"B:func:"<<(int)args[0]<<endl;
}

}
;

int main( int argc, char * argv[])
... {
TMyEventFirer
<int>firer;//事件源
Aa;//事件处理对象
Bb;//事件处理对象

//添加A对象的事件处理
firer.MyEvent+=make_pair<TObject*,TEvent<int>::TEventHandler>(&a,static_cast<TEvent<int>::TEventHandler>(&A::func));

//添加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];

//初始化
args[0]=999;

//激发事件
firer.fireEvent(args);
system(
"pause");

return0;
}

相比较原来版本,最大的改动是保存事件处理方法的容器从数组改成了multi_map.

typedef multimap<TObject*, TEventHandler > TEventMap;

改动的目的是,实现一次性注销指定侦听对象的所有注册事件,以及避免原理方案中同一侦听者同一个事件被注册多次就触发多次的问题.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值