POCO C 库学习和分析 -- 通知和事件 (四) 下载本文

内容发布更新时间 : 2024/5/4 13:46:09星期一 下面是文章的全部内容请认真阅读。

POCO C++库学习和分析 -- 通知和事件 (四)

5. 事件

Poco中的事件和代理概念来自于C#。对于事件的使用者,也就是调用方来说,用法非常的简单。

5.1 从例子说起

首先让我们来看一个同步事件例子,然后再继续我们的讨论:

[cpp]

1. #include \ 2. #include \ 3. #include 4.

5. using Poco::BasicEvent; 6. using Poco::Delegate; 7.

8. class Source 9. { 10. public:

11. BasicEvent theEvent; 12. void fireEvent(int n) 13. {

14. theEvent(this, n);

15. // theEvent.notify(this, n); // alternative syntax 16. } 17. }; 18.

19. class Target 20. { 21. public:

22. void onEvent(const void* pSender, int& arg) 23. {

24. std::cout << \ << arg << std::endl; 25. } 26. }; 27.

28. int main(int argc, char** argv) 29. {

30. Source source; 31. Target target;

32. source.theEvent += Poco::delegate(&target, &Target::onEvent); 33. source.fireEvent(42);

34. source.theEvent -= Poco::delegate(&target, &Target::onEvent);

1

35.

36. return 0; 37. }

从上面的代码里,我们可以清晰的看到几个部分,数据源Source,事件BasicEvent,目标对象Target。 其中source.theEvent += Poco::delegate(&target, &Target::onEvent)完成了,目标向数据源事件注册的过程。大家都知道在C++中,程序运行是落实到类的实例的,看一下消息传递的过程,Poco是如何解决这个问题。target是目标对象实例,Target::onEvent目标对象处理事件的函数入口地址。source.fireEvent(42)触发事件运行,其定义为:

[cpp]

1. void fireEvent(int n) 2. {

3. theEvent(this, n);

4. // theEvent.notify(this, n); // alternative syntax 5. }

theEvent(this, n)中存在两个参数,其中n为Target::onEvent(const void* pSender, int& arg)处理函数的参数,可理解为消息或者事件内容;this给出了触发源实例的信息。

ok。这样消息的传递流程出来了。消息源实例的地址,消息内容,目标实例地址,目标实例类的处理函数入口地址。使用者填入上述信息就可以传递消息了。相当简单。

而对于事件的开发者,如何实现上述功能。这是另外一码事,用C++实现这么一个功能还是挺复杂的一件事。看一下使用语言的方式,想一下用到的C++技术: 1. +=/-= 重载

[cpp]

1. source.theEvent += Poco::delegate(&target, &Target::onEvent);

2. 仿函式

[cpp]

1. theEvent(this, n);

3. 模板

开发者是不应该限定使用者发送消息的类以及接受消息类的类型的,因此C++中能够完成此功能的技术只有模板了。关于模板编程还想聊上几句。STL的特点在于算法和数据结构的分离,这个其实也是泛型编程的特点。如果把使用者对于类的应用过程看做算法过程的话,就可以对这个过程进行泛型编程。同时应该注意的是,算法和数据结构是存在关联的,这是隐含在泛型编程中的,能够使用某种算法的数据结构一定是符合该种算法要求的。

就拿Poco中事件的委托Delegate来说,目标对象处理事件的函数入口是存在某种假设的。Poco中假设入口函数必须是如下形式之一:

[cpp]

1. void (TObj::*NotifyMethod)(const void*, TArgs&);

2

2. void (TObj::*NotifyMethod)(TArgs&); 3. void (*NotifyMethod)(const void*, TArgs&); 4. void (*NotifyMethod)(void*, TArgs&);

5.2 事件的实现

下面一张图是Poco中Event的类图:

下面另一张图是Poco中Event流动的过程:

3