设为首页 加入收藏

TOP

9.9.7 委托和事件(5)
2013-10-07 12:40:58 来源: 作者: 【 】 浏览:61
Tags:9.9.7 委托 事件

9.9.7  委托和事件(5)

Door类还有一个触发两次Knock事件的公有函数TriggerEvent(),两次触发使用不同的实参。这两个实参将被传递给已注册的接收Knock事件通知的函数。我们看到,触发事件实质上与调用委托相同。

我们可以像下面这样定义一个能够处理Knock事件的类:

  1. public ref class AnswerDoor  
  2. {  
  3. public:  
  4. void ImIn(String^ name)  
  5. {  
  6. Console::WriteLine(L"Come in {0}, it's open.",name);  
  7. }  
  8.  
  9. void ImOut(String^ name)  
  10. {  
  11. Console::WriteLine(L"Go away {0}, I'm out.",name);  
  12. }  
  13. }; 

AnswerDoor类有两个能够处理Knock事件的公有函数成员,因为二者的形参列表和返回类型与DoorHandler委托的声明所指定的一致。

在能够注册将接收Knock事件通知的函数之前,我们需要创建一个Door对象。创建Door对象的方法如下:

  1. Door^ door = gcnew Door; 

现在,我们可以像下面这样,注册用来接收Door对象中Knock事件通知的函数:

  1. AnswerDoor^ answer = gcnew AnswerDoor;  
  2. door->Knock += gcnew DoorHandler(answer, &AnswerDoor::ImIn); 

第一条语句创建一个AnswerDoor类型的对象,我们需要该对象,因为ImIn()和ImOut()函数不是静态类成员。然后,我们将DoorHandler委托类型的一个实例与door的Knock成员相加。这完全就是给委托添加函数指针的过程,我们可以以相同的方式,添加更多的当Knock事件被触发时将被调用的事件处理函数。我们可以在示例中看一看处理事件的过程。

试一试:处理事件

该示例使用前面的几个类来定义、触发和处理事件:

  1. // Ex9_19.cpp : main project file.  
  2. // Defining, triggering and handling events.  
  3. #include "stdafx.h"  
  4.  
  5. using namespace System;  
  6.  
  7. public delegate void DoorHandler(String^ str);  
  8.  
  9. // Class with an event member  
  10. public ref class Door  
  11. {  
  12. public:  
  13. // An event that will call functions associated  
  14. // with an DoorHandler delegate object  
  15. event DoorHandler^ Knock;  
  16.  
  17. // Function to trigger events  
  18. void TriggerEvents()  
  19. {  
  20. Knock(L"Fred");  
  21. Knock(L"Jane");  
  22. }  
  23. };  
  24.  
  25. // Class defining handler functions for Knock events  
  26. public ref class AnswerDoor  
  27. {  
  28. public:  
  29. void ImIn(String^ name)  
  30. {  
  31. Console::WriteLine(L"Come in {0}, it's open.",name);  
  32. }  
  33.  
  34. void ImOut(String^ name)  
  35. {  
  36. Console::WriteLine(L"Go away {0}, I'm out.",name);  
  37. }  
  38. };  
  39.  
  40.  
  41. int main(array<System::String ^> ^args)  
  42. {  
  43. Door^ door = gcnew Door;  
  44. AnswerDoor^ answer = gcnew AnswerDoor;  
  45.  
  46. // Add handler for Knock event member of door  
  47. door->Knock += gcnew DoorHandler(answer, &AnswerDoor::ImIn);  
  48.  
  49. door->TriggerEvents(); // Trigger Knock events  
  50. // Change the way a knock is dealt with  
  51. door->Knock -gcnew DoorHandler(answer, &AnswerDoor::ImIn);  
  52. door->Knock += gcnew DoorHandler(answer, &AnswerDoor::ImOut);  
  53. door->TriggerEvents(); // Trigger Knock events  
  54. return 0;  

执行该示例产生下面的输出:

  1. Come in Fred, it's open.  
  2. Come in Jane, it's open.  
  3. Go away Fred, I'm out.  
  4. Go away Jane, I'm out. 

示例说明

我们在main()中首先创建了两个对象:

  1. Door^ door = gcnew Door;  
  2. AnswerDoor^ answer = gcnew AnswerDoor; 

对象door有一个事件成员Knock,对象answer有两个可以处理Knock事件的成员函数。

下一条语句注册answer对象的ImIn()成员,使之接收door对象中Knock事件的通知:

  1. door->Knock += gcnew DoorHandler(answer, &AnswerDoor::ImIn); 

如果有意义,我们还可以注册其他当触发Knock事件时将被调用的函数。

下一条语句调用door对象的TriggerEvents()成员:

  1. door->TriggerEvents(); // Trigger Knock events 

该语句引起两次Knock事件,实参分别是"Fred"和"Jane"。结果是每次事件调用一次ImIn()函数,从而产生前两行输出。

当然,我们可能希望在不同时间根据实际情况,以不同方式对事件作出响应,这正是main()中后面3条语句所演示的事件处理方法:

  1. door->Knock -gcnew DoorHandler(answer, &AnswerDoor::ImIn);  
  2. door->Knock += gcnew DoorHandler(answer, &AnswerDoor::ImOut);  
  3. door->TriggerEvents(); // Trigger Knock events 

第一条语句从事件中删除指向ImIn()函数的指针,第二条语句注册对象answer的ImOut()函数,使之接收Knock事件通知。当Knock事件被第三条语句触发时,被调用的变为ImOut()函数,因此输出结果就发生了变化。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇21.3 管理更新过程 下一篇9.9.7 委托和事件(4)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: