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 阅读(284)
评论(0) 编辑 收藏 引用