作者:袁晓辉(farproc@gmail.com)
声明:
1、 本文为作者原创,如需转载请保持本文的完整性并注明出自 www.farproc.com 和 http://blog.csdn.net/uoyevoli.
2、 本文附件中的源代码你可以免费使用并无需注明出处。
用C++实现事件机制我以前写过一个小例子,但不是很完善,比如Event只能接受全局函数作为handler,类成员方法不可以,还有一个Event只能添加一个handler等……最近我的一个程序刚好要用到Event机制,所以我就抽了些时间,重新实现了一下。这个版本应该说是比较完善的,基本上和C#中的Event一样了。点击这里下载源代码。
要使用Event机制主要用到两个模板类:一个是Delegate,它实现了对C++函数指针的封装,当然,如上所述包括类成员函数的指针;另一个是Event,顾名思义它就是主角“事件”了。用以实现Event机制的所有类都被我“圈”在CppEvent命名空间里了,以免“污染”我们的global namespace。需要提醒的是,这个版本的实现中用到的C++的RTTI,所以用VC编译是别忘了加上/GR编译参数。
一 Delegate
先看一下Delegate类的原型:
namespace CppEvent
{
… …
/*
*公开给程序使用的Delegate模板类
*ReturnType 函数返回值类型
*ArgsType 函数参数类型
*/
template <typename ReturnType = void , typename ArgsType = void*>
class Delegate
{
public:
/*
*构造函数
*用于包装一个对象的成员函数
* object 成员函数所属的对象指针
* function 成员函数的指针
*/
template<class ObjectType>
Delegate(ObjectType* object, ReturnType(ObjectType::*function)(ArgsType))
{
… …
}
/*
*构造函数
*用于包装一个全局函数/类static函数
* function 函数指针
*/
Delegate(ReturnType(*function)(ArgsType))
{
… …
}
};
}
Delegate有两个模板参数ReturnType和ArgsType,第一个指定被代理封装的函数(全局函数/类静态方法或类非成员方法)的返回值类型,第二个指定这个函数的参数类型。注意,由于C++模板只能有固定个数的参数,所以Delegate必须对所封装的函数的参数个数加以限制,也就是说Delegate参数的个数必须固定。既然个数必须固定,那就一个好了,反正我们可以传递结构作参数:)。
Delegate有两个重载的构造函数。第二个是针对全局函数或类静态(static)函数的,只有一个参数,就是把ReturnType作为返回值且带一个ArgsType类型参数的函数的指针(ReturnType(*function)(ArgsType) 注意C风格的函数指针的定义方法)。第一个构造函数是针对类的非静态方法(成员方法)的,它本身也是“模板函数”,模板参数指定被它封装的成员方法所属的类。两个参数,第一个为对象指针,第二个为成员方法的指针。比如有如下类:
class C
{
public:
int M (double param)
{
......
return ......;
}
… …
};
且有一个类C的实例对象objc: