随笔 - 55  文章 - 15  trackbacks - 0
<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

常用链接

留言簿

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

delegate,中文不知道怎么翻译,姑且叫代理吧。

      delegate 的概念其实早就出现,只不过我看到它的时候却是在研究Windows 8时,查阅网上的资料,delegate应该是最先出现在.NET框架中,为的是解决函数指针的不安全性。
      为什么说c++的函数指针不安全呢?想到函数指针你能想到什么?不错,函数的地址,函数的入口点,然后呢?没了,确实就是这些东西,函数指针即没有表示这个函数有什么返回类型,也没有指示这个函数有什么形式的参数,更没有指示有几个参数,你可以随意转换这个函数指针,函数指针是非安全的。
      那么,既然要升级C++,那就为函数指针的安全性做点修改吧。你不是只有个地址吗,没关系,我给你封装一下,封装成一个类,这个类里面你想要的关于这个函数的所有信息都有,甚至这个函数被哪个对象调用我都封装进去。好了吧。
      同其他的类一样,delegate就是一个数据结构,你可以在把它放在类中作为类的数据成员,也可以当成形参,其他类可以怎么折腾,你就可以怎么折腾,从此你就不是一个地址了,你也是可以和别人平起平坐的类了。哇哈哈,高兴坏了。
      言归正传,这里参考MSDN中的官方文档来说明一下delegate:
      原文链接地址:http://msdn.microsoft.com/en-us/library/windows/apps/hh441500(v=vs.110).aspx 

      下面是一个delegate的声明:如果你是在研究Windows 8 的话,^(姑且叫它hat吧)标识符你肯定比较关注,这是说明这个对象是Windows Runtime 类型的,这个对象不用你自己去release,他会采用引用计数技术,当你不需要的时候,后台自动给你释放掉,类似于Java的垃圾回收机制,其实就是把原来的COM中的Release方法给封装了一下。言归正传,这个delegate声明表示,它封装了一个方法,这个方法的返回值是Platform::String^ ,参数也是Platform::String^(这个我就不解释了,都是WinRT里面的新东西,大家WinRT稍微用用就会经常接触这个东西,不同于std::string)
下面又定义了一个借口,我们可以看到NormalizeZipCode^ normFunc可以作为形参。

     下面我们定义一个类来实现这个接口:
 1 ref class ZipCodes: public IZipCodes
 2 {
 3 private:
 4   Platform::String^ LookupFromCityState(Platform::String^ city, Platform::String^ state);
 5   Platform::String^ Normalize(Platform::String^ zip);
 6 public:
 7   Platform::String^ ZipCodeFromCity(Platform::String^ city, Platform::String^ state,
 8     NormalizeZipCode^ normFunc)
 9   {
10     auto zip = LookupFromCityState(city, state);
11     NormalizeZipCode^ func = (normFunc != nullptr ? normFunc :
12       ref new NormalizeZipCode(this, &ZipCodes::Normalize));//这里是重点,给func赋值,可以赋给它一个nullptr指针,也可以new一个给它。
13     return func(zip);
14   }
15 };
     我们看到这个ZipCode类实现了该接口,并实现了这个方法。我们可以这样赋值:NormalizeZipCode ^ func = ref new NormalizeZipCode(&ZipCodes::Normalize);
     调用嘛,大家也看到了,就直接用func(zip)就可以了,这时候,如果传输的normFunc是空值,那么就给func赋值为NormalizeZipCode(this&ZipCodes::Normalize) ,也就是说这时的func就是Normalize函数的代理了,可以直接用func(zip)来调用Normalize(。。。),或许这就是为什么这个类型为什么叫代理类型的原因吧。

      使用上述的类和方法的时候,就跟其他类一样,直接用就行了。
      
 1 IZipCodes ^codes = ref new ZipCodes();
2 auto func = ref new NormalizeZipCode([](Platform::String^ zipcode) {//lambda 表达式
3     return "98103";
4     });
5 
6 auto zip1 = codes->ZipCodeFromCity("Seattle", "WA", nullptr);//这里调用哪个?
7 auto zip2 = codes->ZipCodeFromCity("Seattle", "WA", func);// 这里调用哪个?
8 
      上述的[]应该是lambda表达式,我没有深究。有了解的朋友请给我补补。
posted on 2012-02-14 15:19 Dino-Tech 阅读(289) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理