快速业务通道

实例解析C++/CLI之代理与事件

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30
F2 + F1
  /*7b*/ cd3 -= cd1 + cd1; // F1 + F2 + F2 + F1
  cd3(60);
}

System::Delegate

代理类型的定义,会隐式地创建一个对应的类(class)类型,并且所有的代理类型均从类库System::Delegate继承而来。要定义一个这样的类,唯一的方法就是通过delegate上下文关键字。代理类为隐式的sealed,因此它们不能被用作基类。另外,一个非代理类也不能从System::Delegate继承。

例6演示了几个Delegate函数的用法:

例6:

using namespace System;
delegate void D(int x);
ref class Test
{
  String^ objName;
  public:
   Test(String^ objName)
   {
    this->objName = objName;
   }
   void M(int i)
   {
    Console::WriteLine("Object {0}: {1}", objName, i);
   }
};
void ProcessList(D^ del, int value, Object^ objToExclude);
int main()
{
  /*1*/ Test^ t1 = gcnew Test("t1");
  D^ cd1 = gcnew D(t1, &Test::M);
  /*2*/ Test^ t2 = gcnew Test("t2");
  D^ cd2 = gcnew D(t2, &Test::M);
  /*3*/ Test^ t3 = gcnew Test("t3");
  D^ cd3 = gcnew D(t3, &Test::M);
  /*4*/ D^ list = cd1 + cd2 + cd3 + cd2;
  /*5a*/ ProcessList(list, 100, nullptr);
  /*5b*/ ProcessList(list, 200, t1);
  /*5c*/ ProcessList(list, 300, t2);
  /*6a*/ D^ cd4 = cd1 + cd2;
  /*6b*/ D^ cd5 = (D^)cd4->Clone();
  /*6c*/ ProcessList(cd4, 5, nullptr);
  /*6d*/ ProcessList(cd5, 6, nullptr);
}
void ProcessList(D^ del, int value, Object^ objToExclude)
{
  /*7*/ if (del == nullptr)
  {
   return;
  }
  /*8*/ else if (objToExclude == nullptr)
  {
   del(value);
  }
  else
  {
   /*9*/ array<Delegate^>^ delegateList = del->GetInvocationList();
   for each (Delegate^ d in delegateList)
   {
    /*10*/ if (d->Target != objToExclude)
    {
     /*11*/ ((D^)d)(value);
    }
   }
  }
}

实例函数Test::M与代理类型D相兼容,当调用时,这个函数只是识别出它调用的对象,并带有一个整数参数。

在标号1、2、3中,定义了三个Test类型的对象,并把它们各自与实例函数Test:M包装在单独的代理类型D中。接着,在标号4中,创建了一个四入口的调用列表。

倘若传递进来的调用列表不为空,ProcessList函数将调用在列表中除了特定对象以外的所有函数,例如,在标号5a中,没有排除任何入口,因此所有的函数都会被调用;在标号5b中,t1被排除在外,而标号5c中,与对象t2有关的两个入口都被排除了,结果输出如下:

Object t1: 100
Object t2: 100
Object t3: 100
Object t2: 100
Object t2: 200
Object t3: 200
Object t2: 200
Object t1: 300
Object t3: 300

在标号6b中,调用了Clone创建了代理cd4的一个副本,这个函数返回一个Object^,因此,要把它转换成D^类型。当原始及克隆的代理在标号6c、6d中调用时,结果输出如下:

Object t1: 5
Object t2: 5
Object t1: 6
Object t2: 6

关于函数ProcessList,如果参数中的代理实例为nullptr,即没有调用列表,那它将直接返回;如果排除的对象为nullptr,那么列表中所有的函数都将被调用;如果存在要排除的对象,就要像标号8中那样把调用列表当作代理数组取出,接着,在标号9中逐个排查不相符的入口,最后,在标号10中调用余下的这些函数。尽管在调用列表中每个入口都是Del类型,但GetInvocationList返回一个基类Delegate数组,所以在调用每个代理实例之前,需像标号10那样先转换成类型D。

事件

在C++/

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号