进入旧版 | 服务项目 | 成功案例 | 联系方式 | 过客留言 | 友情链接
   
设为首页
加入收藏
联系我们
网站首页 | 新闻资讯 | 操作系统 | 办公软件 | 网络软件 | 工具软件 | 媒体动画 | 网页制作 | 网站开发 | 程序开发 | 平面设计
Photoshop视频教程 | Word入门 | Flash入门 | JScript | VBScript | ASP | PHP | ADO | 网页特效 | 3DS MAX6.0命令 | 系统进程
您当前的位置:GOODSGY电脑学习网 -> 程序开发 -> VC -> 文章内容  
Visual C++.NET教程:3.10 代 理

3.10     

代理是C++托管扩展中一个崭新的名词,也是一个从字面上不容易理解的名词,其英文是delegate。听起来比boxingunboxing之类名词的神秘色彩又重了几分,那么到底什么是“代理”呢?www.goodsgy.com

提起delegate,开发人员可能不清楚,但是谈到callback,也就是回调函数,便不会感到陌生了。其实,从某种角度上来看,开发人员可以把delegate看作是传统编程中回调函数和函数指针的等价物。www.goodsgy.com

为了更好地理delegate,我们首先回忆一下有关回调函数的内容。关于回调函数,对于经常使用Visual C++SDK的开发人员来讲,应当是十分熟悉的。在标准Win32应用程序中,几乎处处都有回调函数的参与:处于核心位置的窗口过程WNDPROC;调用EnumWindows函数时传递的WNDENUMPROC函数;当我们调用SetWindowsHook给系统挂钩子时传递的HOOKPROC函数;当调用使用线程的APC(异步过程调用)时等等。www.goodsgy.com

对于回调函数概念,用一句简单的话加以概括就是:用户按照系统要求进行自定义的,最后在适当时间由系统来调用的函数。www.goodsgy.com

传统应用程序中,回调机制得以实现的实质是在对应的API函数被调用时,将回调函数本身的地址告诉系统。于是,当系统决定要调用回调函数时,就会根据这个地址来找到回调函数并调用之。但是,有过这方面开发经历的开发人员一定知道,回调函数对系统而言仅仅是一个函数地址,除此之外,没有任何的附加信息,这就存在着类型安全方面的隐患。例如,在进行窗口子类化开发中,必须通过调用SetWindowsLong函数来修改某个窗口过程的地址,并使用自定义窗口过程来处理感兴趣的消息。但是,开发人员最后却忘记了还原(原来被替换的窗口过程指针),这样,就会在应用程序运行过程中或者结束时,遇到可怕的内存访问错误。www.goodsgy.com

但是,对于具备类型安全的托管的应用程序来讲,回调机制(或更为广泛地讲,函数指针)如果单纯依赖地址是不足以实现类型安全的,还必须带有函数的参数个数和每个参数的类型以及函数的返回值类型的详细信息描述,才可以在CLR的帮助下完成引用安全。www.goodsgy.com

所以,delegate和标准的C++函数指针可以说是“形似而神不似”,虽然作用一样,但内部机制有许多区别。www.goodsgy.com

Delegate.NET框架中作为抽象类得以实现。有两类delegatesingle-castmulti-cast。前者由System.Delegate实现,它仅仅可以把函数指针绑定到一个方法上;而后者是由Syetem.MutiCastDelegate来实现的,可以将函数指针绑定到一个或多个方法上。从前面的论述中,我们已经知道了,尽管_delegate关键字使用的语法和标准C++ typedref关键字类似,但是编译器却创建了一个托管的类的定义。这个托管的类具有以下性质:www.goodsgy.com

这个类是从System.DelegateSystem.MuticastDelegate中继承下来的。www.goodsgy.com

这个类的构造函数有两个参数,一个是托管的引用或者干脆为空,另一个是被确定了类型的方法。www.goodsgy.com

这个类中有一个名叫Invoke的方法,对这个方法的调用将真正地激活绑定到delegate的方法。www.goodsgy.com

C++托管扩展中,delegates类型的定义依靠_delegate关键字。这个关键字定义了一个single-cast delegate类型,并指定一个函数标识。这个关键字使用当中的一个变种:_delegate(multicast),用于定义一个muti cast delegate类型,这个类型同样有一个指定的方法标识。www.goodsgy.com

下面我们使用实际的例子来验证和熟悉我们所讲述的知识。这段源程序可以在配书光盘的\SourceList\_Chap03\delegate目录下找到。www.goodsgy.com

Delegate.cppwww.goodsgy.com

--------------------------------------------www.goodsgy.com

#using <mscorlib.dll>www.goodsgy.com

using namespace System;www.goodsgy.com

 www.goodsgy.com

_delegate int GetDayOfWeek(); www.goodsgy.com

 www.goodsgy.com

_gc class MyCalendar www.goodsgy.com

{www.goodsgy.com

public:www.goodsgy.com

   MyCalendar() : m_nDayOfWeek(4) www.goodsgy.com

   {www.goodsgy.com

   }www.goodsgy.com

   int MyGetDayOfWeek() www.goodsgy.com

   { www.goodsgy.com

       return m_nDayOfWeek; www.goodsgy.com

   }www.goodsgy.com

   static int MyStaticGetDayOfWeek() www.goodsgy.com

   {www.goodsgy.com

       return 6; www.goodsgy.com

   }www.goodsgy.com

private:www.goodsgy.com

   int m_nDayOfWeek;www.goodsgy.com

};www.goodsgy.com

 www.goodsgy.com

void main ()www.goodsgy.com

{www.goodsgy.com

   // 定义了delegate类型www.goodsgy.com

   GetDayOfWeek * pGetDayOfWeek; www.goodsgy.com

   int nDayOfWeek;www.goodsgy.com

   www.goodsgy.com

   // delegate绑定到静态方法www.goodsgy.com

   pGetDayOfWeek = new GetDayOfWeek(0, MyCalendar::MyStaticGetDayOfWeek);www.goodsgy.com

   nDayOfWeek = pGetDayOfWeek->Invoke();www.goodsgy.com

   Console::WriteLine(_box(nDayOfWeek)->ToString());www.goodsgy.com

   www.goodsgy.com

   // 绑定到实例方法www.goodsgy.com

   MyCalendar * pcal = new MyCalendar();www.goodsgy.com

   pGetDayOfWeek = new GetDayOfWeek(pcal, &MyCalendar::MyGetDayOfWeek);www.goodsgy.com

   nDayOfWeek = pGetDayOfWeek->Invoke();www.goodsgy.com

   Console::WriteLine(_box(nDayOfWeek)->ToString());www.goodsgy.com

}www.goodsgy.com

以上例子代码是一个很典型的delegate应用,首先使用_delegate关键字定义delegate类型,然后声明并定义一个类来实现静态方法和实例方法。在实际使用中,首先让delegate绑定到可以实现回调的方法,最后,在需要回调的时候调用delegate对象的Invoke方法来触发绑定函数的调用。www.goodsgy.com

另外,为了验证delegate是托管的应用程序的特色,请首先构造上面的例子程序,并使用ILDesam.exe来查看,如图3-10所示。www.goodsgy.com

www.goodsgy.com

3-10  验证托管的程序中的delegatewww.goodsgy.com

请特别注意图3-10中被圈中区域的信息。我们可以从图中清楚地看出,delegate与传统的函数指针有很大的区别,特别是在类型安全方面。www.goodsgy.com

在百度中搜索:Visual C++.NET教程:3.10 代 理
在Google中搜索:Visual C++.NET教程:3.10 代 理
在Yahoo中搜索:Visual C++.NET教程:3.10 代 理

收藏到网摘:新浪VIVI 365key 我摘 POCO网摘 博采中心 YouNote 和讯网摘 天天收藏
[] [返回上一页] [打 印] [收 藏]

 相关文章    最新文章
· 怎样做XP和Vista双系统
· 让Vista搜索屏蔽个人内容
· [组图] 删除VISTA后,怎样删除Vista的Windo..
· Windows Vista中5项被误解的功能
· XP销售大限将至 Vista终盼到出头之日
· Vista设置缓存文件释放系统盘空间
· Vista系统电源管理的几个配置方案
· 你痛恨Vista么?Vista成为全球公敌
· Vista升级程序曝音频驱动故障 用户不满
· 无需额外软件 Vista自动更换IP地址
 
· VC实现系统热键激活后台服务程序
· SEO:关于baidu一些排名规则的讨论
· More Effective C++:不要重载的操作符
· VC利用boost库解析正则表达式
· [图文] 用VC实现对超长数据库字段的操作
· More Effective C++:防止资源泄漏
· 用VC#2005解析含有多种格式的文本文件
· C++中禁止异常信息传递到析构函数外
· [图文] Visual C# 2005实现控件中捕获按键..
· C++中理解“传递参数”和异常之间的差异

∷相关文章评论∷    (评论内容只代表网友观点,与本站立场无关!) [更多评论…]
站内搜索

精彩图文
  网站导航  
操作系统 办公软件 网络软件
Vista Windows2003 WindowsXP Windows2000/NT Windows9X/ME Linux 其他 Word Excel Powerpoint Outlook 金山系列 其他 网页浏览 上传下载 联络聊天 邮件工具 服务器软件 网络辅助
工具软件 媒体动画 网页制作
系统工具 媒体工具 压缩工具 图文处理 文件管理 其他 3DMAX Authorware Director Maya 视频处理 其他 Flash Dreamweaver FireWorks FrontPage LiveMotion Golive HTML/CSS 其它
网站开发 平面设计 程序设计
ASP JSP PHP CGI JavaScript VBScript XML/SOAP Web服务器 Photoshop PhotoImpact CorelDraw Illustrator Freehand 设计欣赏 其他 VB VC .NET C/C++ DELPHI JAVA

冀ICP备05019428号
Copyright © 2004-2008 电脑学习网 Inc.All rights reserved.
TEL:13832340607
QQ:39873155
E_Mail:goodsgy(#)hotmail.com   (把(#)替换成@)
MSN:goodsgy(#)hotmail.com   (把(#)替换成@)