C 模拟event关键字具体实现方案
创始人
2024-06-23 00:31:01
0次

在C++编程语言中,其实也是有它不能够支持的功能,但是可以通过各种方法来进行模拟以达到编程人员程序开发的需求。在这里我们就会为大家详细介绍有关C++模拟event关键字的相关操作方法。

在VC6中新建一个win32 console app,命名为“cppevent“。新建一个.h头文件,命名为“event.h”,代码如下:

  1. //event.h  
  2. template  
  3. class event  
  4. {  
  5. private:  
  6. Handler m_Handler;  
  7. protected:  
  8. //模拟C# event 的add/remove访问器  
  9. //如果要重新实现add/remove请在派生类中重写这两个函数  
  10. virtual void add(const Handler value){m_Handler = value;};  
  11. virtual void remove(const Handler value)
    {if(value == m_Handler)m_Handler = NULL;};  
  12. public:  
  13. //构造函数  
  14. event():m_Handler(NULL){}  
  15. //+= 操作符  
  16. event& operator += (const Handler value)  
  17. {  
  18. add(value);  
  19. return *this;  
  20. }  
  21. //-=操作符  
  22. event& operator -= (const Handler value)  
  23. {  
  24. remove(value);  
  25. return *this;  
  26. }  
  27. //PFN_EVENT_HANDLE 操作符  
  28. operator Handler()  
  29. {  
  30. return m_Handler;  
  31. }  
  32. }; 

为了能够在在C++模拟event关键字中定义是指定事件处理函数的原型,我使用了template,为了能和C#一样用+=和-=来定制和撤消事件,我重载了这两个操作符(C#不支持操作符重载),为了能像C#一样直接把event当做函数调用,我有重载了Handler自定义转换操作符,可惜的是,这一点模拟得不是很像,在调用时还必须来一次强制转换才可以:(,具体参看后面的代码:

C++版的MyClass如下:

  1. //MyClass.h  
  2. #include "event.h"  
  3. //定义EventHandler的函数指针类型  
  4. typedef void(*EventHandler)();   
  5. class MyClass  
  6. {  
  7. public:  
  8. //构造函数  
  9. MyClass(){};  
  10. //声明一个事件  
  11. event AEvent;  
  12. //激发事件  
  13. void FireEvent()  
  14. {  
  15. if(AEvent != NULL)   
  16. {  
  17. //C++中必须用EventHandler进行强制类型转换  
  18. ((EventHandler)AEvent)();  
  19. };  
  20. }  
  21. }; 

 

和C#版的MyClass比较一下你就会发现代码非常接近,当然,C#是在语言级直接支持event关键字的,而C++不支持,用模板类代替,所以声明事件的代码有些不一样。还有就是FireEvent()中C++不能把event对象直接当做函数来调用,多了强制类型转换。

C++版的客户代码如下:

  1. // cppevent.cpp : Defines the entry point for 
    the console application.  
  2. //  
  3. #include "stdafx.h"  
  4. #include "MyClass.h"  
  5. //向前声明  
  6. void MyEventHandler();   
  7. int main(int argc, char* argv[])  
  8. {  
  9. MyClass Obj;  
  10. Obj.AEvent += MyEventHandler;//定制事件  
  11. Obj.FireEvent();//这行将导致MyEventHandler被调用  
  12. Obj.AEvent -= MyEventHandler;//撤消事件  
  13. Obj.FireEvent();//这个将不会引发事件  
  14. printf("结束!\n");  
  15. char n;  
  16. scanf("%c", &n);  
  17. return 0;  
  18. }  
  19. void MyEventHandler()  
  20. {  
  21. printf("This is a event!\n");  
  22. } 

 

我们可以看到,可C#版的客户代码相比,核心部分是非常接近的,我们已经可以和C#一样用“+=”和“-=”来定制事件和撤消事件定制,并在Obj的FireEvent()被调用时收到事件通知,输出文本。#t#

鉴于篇幅的原因,我们没有仔细比较两个版本的event的add和remove访问器/成员函数,其实二者也是非常类似的,你可以自己试试。C++版的event的add和remove均为virtual的,你可以从event类继承出来一个MyEvent类,然后重新实现这两个函数,就可以定制自己的add和remove了。这和C#的add/remove访问器的也是非常相像的。

 

总结

通过C++模拟event关键字的实现,我们可以从更深的层次理解C#的event机制,更重要的是我们用自己所熟悉的东西(C++,模板类)来模仿并解释了我们目前还不太熟悉的东西(C#,event)。

其实,C#的delegate就是C++的函数指针,C# event的核心机制就是C++中的模板(定义event时表现出来)和运算符重载(+=、-=和直接把event当做函数调用)的结合体。C#把C++中容易出错的部分用“新特性”封装了起来,把这部分工作从programmer身上转移到了compiler身上,让我们把更多的精力集中到业务逻辑的处理上。

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
只需三步,让你掌握阿尔法路由器... 请参照以下阿尔法路由器设置方法,通过浏览器进入及设置宽带路由器。经过这三个步骤的设置,基本上能够熟悉...
如何更省钱? 近期特价热门硒鼓... 如今激光打印设备已经成为商务或企业的绝对主力办公设备,但采购者往往忽视了激光打印设备所用的耗材,相对...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...