文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C++中event关键字有什么用

2023-06-17 17:00

关注

C++中event关键字有什么用,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

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

  1. //event.h  

  2. template <typename Handler> 

  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如下:

//MyClass.h  #include "event.h"  //定义EventHandler的函数指针类型  typedef void(*EventHandler)();   class MyClass  {  public:  //构造函数  MyClass(){};  //声明一个事件  event<EventHandler> AEvent;  //激发事件  void FireEvent()  {  if(AEvent != NULL)   {  //C++中必须用EventHandler进行强制类型转换  ((EventHandler)AEvent)();  };  }  };

和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");  

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

鉴于篇幅的原因,我们没有仔细比较两个版本的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身上,让我们把更多的精力集中到业务逻辑的处理上。

看完上述内容,你们掌握C++中event关键字有什么用的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯