委托是一种很实用的设计方法,一个模块可以将某些事情委托给其他实体去做,而对于模块本身不需要知道受委托的实体是什么,它只知道这个实体遵循某种接口规范。回调函数可以认为是一种委托,它在Windows编程中起了非常重要的作用。
委托的一个重要应用是事件机制,假设有类A负责加载数据,类B用于实时显示A的加载进度,那么A必须向B引发一些事件,以表明它的加载进度。要实现这种机制可以用观察者模式,Java即使用观察者模式来实现事件监听的。Delphi使用了类似回调函数的技术来实现事件,这样也有一些好处,就是简单高效,对于一些轻量级的应用还是非常合适的。
C++如何实现事件,当然可以用观察者模式来实现,不过这里要介绍另一种方法,就是用成员函数指针,这种方法更类似于Delphi的事件,优点是简单高效。
下面是我写的两个源文件,对通用事件提供了支持,其中涉及到成员函数指针的知识,我就不班门弄斧了,直接给就出源代码如下:
EventUtils.h
#ifndef EVENTUTILS_H_
#define EVENTUTILS_H_
// 用于欺骗编译器,传递This指针
class CMemFunObj
{
};
// 通用函数类型
typedef void (CMemFunObj:: *PFNMEMFUN)();
// 成员函数结构
typedef struct tagMEMBERFUN {
CMemFunObj *Self;
PFNMEMFUN pfnAddr;
} MEMBERFUN, *PMEMBERFUN;
// 生成成员函数结构
MEMBERFUN MakeMemberFun(CMemFunObj *Self, PFNMEMFUN pfnAddr);