引言
在。NET中,委托被用来实现事件处理。它允许一个类(方法)先注册一个事件,然后当此事件被引发时此注册的方法就会被调用。在非。Net环境的C++中,这并不是一件容易的事,尤其是类的非静态成员函数,要做为回调函数就更困难了。本文的目标就是给出一种解决方案, 使类的静态成员函数,非静态成员函数,还有类非成员函数都能像回调函数一样使用。这个实现非常重视类型安全,为了保持类型安全我们省去了某些特性的实现。
什么是委托?
。NET框架中对委托的定义如下:
"委托是一个可以保持对某个方法引用的类。不同于其它类,委托类有自己的签名(返回值,参数类型,个数),并且只能引用与其签名匹配的方法。委托其实可以看成一个类型安全的函数指针或回调函数。
一个提供了委托的类允许其它函数或类在此委托上注册事件处理函数。然后当这个类的委托被执行时,就会遍历其处理函数列表,逐个调用,并传入传给委托的信息。而提供委托的那个类不需要知道委托注册了多少处理函数,委托自己会处理这一切。
正文
函数对象(functor)概述
我们用函数对象(functor, function object)来实现C++中的委托。这允许一个非静态成员函数能在特定对象的环境中被调用。我们用模板技术来保证任何类类型都能在其上使用。一个基本的函数对象(functor)定义如下:
template<class T> class Functor { public: // Constructor takes the values and stores them Functor(T *pObj, int (T::*pFunc)(int)) { m_pObject = pObj; m_pFunction = pFunc; } // Invokes the stored function intoperator ()(int p) { return (m_pObject->*m_pFunction)(p); } private: T *m_pObject; // Pointer to the object int (T::*m_pFunction)(int); // Pointer to the function }; |
这个函数对象(functor)使用的函数格式为:返回类型为int,带一个类型为int的参数。操作符operator ()是函数对象的关键。它使一个函数对象(functor)使用起来和函数调用一样。它的工作就是每次执行时调用保存在类内部的函数指针。以下代码展示了如何使用这个函数对象(functor):