快速业务通道

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

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30
;Comparing {0} and {1}" "using CompareIgnoreCase", s1, s2);
   // ...
   return 0;
  }
};
delegate int Compare(String^ s1, String^ s2);
/*1*/
Compare^ FindComparisonMethod()
{
  // ...
}
void Sort(Compare^ compare)
{
  int result;
  /*3*/ result = compare("Hello", "Hello");
  /*4*/ result = compare("Hello", "HELLO");
  /*5*/ result = compare("Hello", "Hell");
}
int main()
{
  /*6*/ Sort(gcnew Compare(&StrCompare::CompareIgnoreCase));
  /*7*/ Sort(FindComparisonMethod());
  /*8*/ FindComparisonMethod()("Red", "RED");
}

Compare代理类型可对任意接受两个String^参数并返回一个int结果的函数进行包装,在此,有两个函数为StrCompare::CompareExact和StrCompare::CompareIgnoreCase。

在标号6中,创建了一个Compare代理类型的实例,用它来包装StrCompare::CompareIgnoreCase,并把此代理句柄传递给Sort函数,其将会利用比较函数进一步进行处理。

正如大家所看到的,Sort可接受一个代理类型的参数--而此参数可像其他函数参数一样,可为传值、传址、传引用。

在标号7中,调用了FindComparisonMethod函数,其返回一个Del代理类型,接着在标号7及8中调用了包装过的函数。此处要重点说一下标号8:首先,FindComparisonMethod函数是被调用来获取代理实例--其常用于调用底层函数;其次,这两个函数的调用操作符都有同等的优先级,所以它们从左至右调用。

FindComparisonMethod函数中也用了一些逻辑用于确定到底需要包装哪个函数,此处就未作详细说明了。

代理类型的兼容性

一个代理类型只与它自身相兼容,与其他任何代理类型都不兼容,即使其他类型的包装函数均为同一类型。请看例3,非常明显,代理类型D1与函数A::M1与A::M2兼容,代理类型D2也与这些函数兼容,然而,这两个代理类型在标号5、6、8、9中并不能互换使用。

例3:

delegate void D1();
delegate void D2();
public struct A
{
  static void M1() { /* ... */ }
  static void M2() { /* ... */ }
};
void X(D1^ m) { /* ... */ }
void Y(D2^ n) { /* ... */ }
int main()
{
  D1^ d1;
  /*1*/ d1 = gcnew D1(&A::M1); //兼容
  /*2*/ d1 = gcnew D1(&A::M2); //兼容
  D2^ d2;
  /*3*/ d2 = gcnew D2(&A::M1); //兼容
  /*4*/ d2 = gcnew D2(&A::M2); //兼容
  /*5*/ d1 = d2; //不兼容
  /*6*/ d2 = d1; //不兼容
  /*7*/ X(d1); //兼容
  /*8*/ X(d2); //不兼容
  /*9*/ Y(d1); //不兼容
  /*10*/ Y(d2); //兼容
}

代理类型的合并

一个代理实例实际上能包装多个函数,在这种情况下,被包装的函数集被维护在一个调用列表中,当合并两个代理实例时,它们的调用列表也以指定的顺序连接起来,并产生一个新的列表,而现有的两个列表并没有发生改变。当从调用列表中移除一个或多个函数时,也会产生一个新的列表,且原始列表不会发生变化。请看例4中的代码,每个函数调用后的输出都写在相应函数后。

例4:

using namespace System;
delegate void D(int x);
ref struct Actions
{
  static void F1(int i)
  {
   Console::WriteLine("Actions::F1: {0}", i);
  }
  static void F2(int i)
  {
   Console::WriteLine("Actions::F2: {0}", i);
  }
  void F3(int i)
  {
   Console::WriteLine("instance of Actions::F3: {0}", i);
  }
};
int main()
{
  /*1*/ D^ cd1 = gcnew D(&Actions::F1); //包含F1的调用列表
  cd1(

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号