C++事件机制(上篇)-- Observer模式

来源:互联网 发布:java单机游戏破解版 编辑:程序博客网 时间:2024/06/02 08:49

 C++事件机制(上篇)-- Observer模式

 

简介:

本文通过上中下三篇文章来分析c++事件机制的各个方面,并实作出一个c++的事件库。

 

用过C#的朋友,一定对于C#的事件机制感觉很爽,来我们看一看一个C#的例子。

class Test

    {

       public delegate void ClickHandle(int X,int Y);

        public event ClickHandle OnClickEvent;

       public void OnClick()

       {

           OnClickEvent(3,4);

       }

    }

在使用时用

Test test = new Test();

test.OnClickEvent+=new Test.ClickHandle(test_OnClickEvent);

就完成了事件的注册,非常之方便简洁。C#的事件基础是委托,并在此之上形成了多播委托。

那么C++能否做到呢?C++社团的理念是首先C++一定能做到,如果C++没有提供,那么动手做一个,最后是很重要的一条尽量的节省成本或者表述为"不为不需要的东西付出成本"

我想看这篇文章的很多朋友已是C++的老手,相信对于C#的这种用法是羡慕良久,在工作上可能也使用过网上的解决方案,比如在CodeProject上就有不少该类实现,比较有名的我想是以下几篇

Don Clugston的大作,见 http://www.codeproject.com/KB/cpp/FastDelegate.aspx;

JaeWook Choi的大作,见 http://www.codeproject.com/KB/cpp/fd.aspx;

Sergey Ryazanov的大作,见 http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx;

他们各自采用了不同的方法,有的利用“hack方式”,有的利用了标准c++中不起眼的角落的规则,这些不过都还没达到我心中完美的c++事件实现,或者说是各有千秋但均不完善。他们的方法我会在下篇文章中进行介绍。当然,你可以等待C++1X的标准中包含delegateevent关键字,不过可能性不是很大,因为C++老大很反感增加关键字,因为他说必需保证要与上千万行已存在的代码兼容。

C++从来不会让我们失望。不过溯本正源,我们首先来看一看C++中传统的“事件”方式是如何实现的,这能让我们了解事件的本质,以及事件机制的成本,也可以把它作为我们事件方式成本的考量。GOF中提出的23种设计模式中的Observer模式就是来实现“事件模型",看看这种模式是干什么的定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新这就是事件机制的精髓,举个简单例子,张三结婚了,他会给每个同事发一个请柬告诉大家“XXXXXXXX日,我结婚,有红包的赶快拿来!”,于是各位同仁不得不从微薄的薪水中挤出几张红票子给张三。这就是事件。其实从某种意思上讲windows的消息机制也是一种事件机制,不过它是系统角度实现的,而非语言层面的。费话少说有,我们首先来看一看Observer的图例,老手自然不用我多说,自然早已山水了于胸了,新手么,我建议你看看GOF的书。

observer图例

 

下面是一个subject的具体实现

class Subject {
public:
    virtual ~Subject();
    virtual void Attach(Observer*);
    virtual void Detach(Observer*);
    virtual void Notify();
protected:
    Subject();
private:
    list<Observer*> *_observers;
};

当我们使用时可以用

ConcreteSubjectObj.Attach(&ConcreteObserverObj1);

ConcreteSubjectObj.Attach(&ConcreteObserverObj2);

这样就把ConcreteObserverObj1ConcreteObserverObj2置于我们的事件通知链中,当ConcreteSubjectObj调用Notify()时,便会使用 list中的每个对象进行相应的操作。于是就完成了我们的事件模型。这种方式没有用到模板之类的东东,因此无论是初涉C++的朋友,还是C++的老手应该都容易了解,只是它的问题是过于繁琐,写一个类的事件尚易,写很多个类的事件则非常的麻烦,而且使用了C++中比较恶心的多继承,,语法上也是非常地不直观不KISS

但是它也并非一无是处,首先它让我们了解到多播事件必需有一个“链表”之类的东东来保存信息,其次它在所有的C++编译器中都能执行。

 

嗯,我要的不是这个,我要的是类似于下面的东东

typedef delegate<void(int,int)> ClickHandle; //声明委托

 

event<ClickHandler> OnClick;   //声明事件

 

test.OnClick+= ClickHandle(obj,ObjOnClick); //注册事件

它应该有以下几个优点:

1、  类似于C#的语法,或者是非常便于书写

2、  易于使用,而且支持多播委托,甚至是异步多播委托

3、  不为不需的功能付出成本

  4/、尽可能地靠近C++标准,(完全符合C++标准的编译器好象还没有吧?)

 

下一篇预告,将带领大家领略前文中提到过三大高手的不同实现。哈哈,看高手比武是很有趣的。

 

原创粉丝点击