事件编程(二)
2007-03-15 21:54:00 来源:WEB开发网核心提示: STL 的高手们也许会问:为什么我不使用 mem_fun 适配器直接将 IPrimeEvents::OnProgress 转换为函数对象,因为 OnProgress 是虚拟函数,事件编程(二)(4),我不能适配一个虚拟函数,如果这样做,纯虚拟函数没有定义——除非它是
STL 的高手们也许会问:为什么我不使用 mem_fun 适配器直接将 IPrimeEvents::OnProgress 转换为函数对象。因为 OnProgress 是虚拟函数,我不能适配一个虚拟函数。如果这样做,要触及到基类。如果你使用 Boost 库,可以用其捆绑适配器直接将 OnFoo 这样的虚拟事件处理器转换为仿函数,不用编写仿函数。如果你不明白我所讲的这些内容,不用害怕,不看这些内容好了。
当然,我还需要一个 Done 事件的 NotifyDone。由于 Done 没有参数,构造函数也没有:
class NotifyDone : public unary_function
{
public:
NotifyDone() { }
void operator()(IPrimeEvents* obj)
{
obj->OnDone();
}
};
现在我有了自己的仿函数类,我可以用 for_each 代替手工迭代客户机列表。可我把它们放在哪呢?仿函数属于与事件说明有关的范畴,所以我把它们放在 IPrimeEvents 接口中,用嵌套类的形式。代码如 Figure 2 所示。细心的读者会注意到我在两个地方还做了细小的恶修改。仿函数的命名没有用 NotifyProgress,而是叫做 Progress。稍后你会明白这样做使代码更易读;还有就是我没有把事件处理器都声明为纯虚拟函数,而是将它们定义为空实现。IPrimeEvents 只有两个事件,但对于一般的事件机制来说,如果程序员感兴趣的的处理并不多,但要让他们实现每一个事件处理器似乎不是很友好。所以这里每个处理器默认实现什么也不做。为了使基类抽象化,我声明了一个纯虚拟析构函数。当你想抽象化一个没有任何纯虚函数的基类时,这是一个标准的C++技巧。唯一的要做的是你必须定义一个析构函数。纯虚拟函数没有定义——除非它是析构函数。既然每一个派生类的析构都调用其基类的析构函数,那么基类需要一个实现,即便它是纯虚拟的:
[]
更多精彩
赞助商链接