动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > 软件工程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ 软件工程 ]的信息

本月文章推荐
.软件自动化测试实例分析.
.成功测试管理的九大原则.
.七问七答 SOA.
.关于.NET动态代理的介绍和应用简.
.项目成功的12个关键原则.
.CMMI模型对软件测试技术的扩充.
.05软件技术大会预览:SOA由概念走.
..NET中微软地图MapPoint2004编程.
.历史十大黑客事件:不堪一击的系.
.测试过程改进的缺陷漏测分析.
.程序开发过程.
.软件的架构与设计模式之层次原则.
.小心借情人节传播的QQ尾巴(第3版.
.规划SOA(2)构建SOA路线图.
.Web服务轻松进行企业应用集成.
.数据库设计说明书.
.软件质量评价标准.
.解析UML的动态建模机制.
.要意识到僵尸网络日益增长的威胁.
.探究需求管理的本质.

再谈多态—向上映射及VMT/DMT

发表日期:2008-3-23 |


版权所有:Nicrosoft
文章来源:东日制作室
在《浅谈多态——概念描述》一文中,提到多态的本质就是“将子类类型的指针赋值给父类类型的指针”。那么,为什麽这种赋值是答应的,或者说是安全的呢?反过来行不行?虚函数的动态绑定是如何实现的呢?这些问题都将在本文得到解答。

假设有如下代码(Object Pascal语言描述):

T1 = class
private
member1 : integer;
public
function func1 : Integer; virtual;
function func2 : Integer; virtual;
function func3 : Integer; virtual;
end;

T2 = class(T1)
private
member2 : integer;
public
function func1 : Integer; override;
function func2 : Integer; override;
end;

最终结果是,T1类的实例的内存分布图如下(仅说明原理,并不表示编译器一定也是如此实现):

再谈多态—向上映射及VMT/DMT

其中,vptr是编译器自动加入的一个成员指针(称为虚指针)。只有存在虚函数或动态函数或纯虚函数的类才会被编译器加入这个成员指针,该指针指向一个称为“虚函数表”(Object Pascal中成为“虚方法表”——VMT)的内存区域。虚函数表中,保存了每一个虚函数的入口地址。

T2类的实例的内存分布图如下:

再谈多态—向上映射及VMT/DMT

从图中我们可以知道,子类对象所占的空间大于父类对象所占空间。因此,当发生将子类类型的指针赋值给父类类型的指针的赋值时(即所谓的“向上映射”),也就是父类类型的指针指向了子类类型的对象所占的内存空间,那么,很显然,可以保证父类类型指针的可访问范围都是有效,所以这种“向上映射”是绝对安全的(所谓“向上”是指类层次的上下关系,父类在上,子类在下)。这种赋值是得到编译器认可的。

也可以很轻易得出结论,“向下映射”则未必安全(除非程序员真正知道指针所指对象的实际类型)。因此,这种赋值是不被编译器答应的,当然,程序员可以通过类似 T1(Obj) 的形式进行强制类型转换,但这种强制类型转换很不安全(可以发生在任何类和类之间),Object Pascal推荐使用 as 算符进行类型之间的转换,如: (Obj as T1),使用 as 算符,编译器会检查对象类型和目标类型是否相容。
  假如相容,转换被答应,否则编译出错。 进入讨论组讨论。

接着,我们看看虚函数的动态绑定是如何实现的。先看如下代码:

procedure Test;
var O : T1;
begin
O := T2.Create;
O.func1;
O.func3;
O.Free;
end;

看着上面的内存布局图,当执行 O := T2.Create; 后,一个 T1 类型的指针指向 T2 实体。执行O.func1 时,编译器通过 vptr 找到虚函数表,在虚函数表中定位到了 T2.func1(由于 T1.func1 被“覆盖”了,因此虚函数表中找不到 T1.func1),于是,T2.func1 被调用,这就是动态绑定!但由于T2 没有重写 func3,因此 O.func3 将调用 T1.func3,这一点在虚函数表中也可以很明显看出来。

好了,说到这里,我想动态绑定已经说的非常清楚了,说明一点,本文虽然以 Object Pascal代码为例,但其原理对于 C++也同样有效。C++与Object Pascal(甚至不同C++编译器之间)的区别仅在于类成员及vptr在内存中分布的位置而已。


那么,最后再谈一下 Object Pascal 独有的 DMT(动态方法表)吧。在VMT中,我们看到,子类的虚函数表完全继续了父类的虚函数表,只是将被覆盖了的虚函数的地址改变了。每个子类都有一份自己的虚函数表,可以想象,随着类层次的扩展,假如类层次非常深,或者子类的数量非常多的话,虚函数表将称为占用内存量非常大的东西(即所谓的“类爆炸”)。为了防止这种情况, Object Pascal 引入了DMT。对于程序员来说,区别仅在于使用“dynamic”要害字代替“virtual”要害字,所实现的功能也完全一样。

假如把本文开头的那段代码重写如下(用 dynamic 代替 virtual):

T1 = class
private
member1 : integer;
public
function func1 : Integer; dynamic;
function func2 : Integer; dynamic;
function func3 : Integer; dynamic;
end;

T2 = class(T1)
private
member2 : integer;
public
function func1 : Integer; override;
function func2 : Integer; override;
end;

那么,T1 的内存分布图没有改变,而 T2 实例的就不一样了:

再谈多态—向上映射及VMT/DMT

可以看到,在 T2 的动态方法表中,没有被覆盖的 T1.func3 消失了。因此:

procedure Test;
var O : T1;
begin
O := T2.Create;
O.func3;
O.Free;
end;

O.func3 这一句代码将被编译器做更多的处理:找到 T1 类的 func3 函数的入口地址,然后再调
用。

比较一下 VMT 和 DMT 的区别:

VMT 中的虚函数非常齐全,因此对每个虚函数的入口地址只需要简单的 [vptr + n] 的运算即可得到,但是 VMT 轻易消耗内存(有冗余)。而 DMT 比较节省空间,但要定位到没有被覆盖的函数的入口地址时,将非常耗费时间。

一般情况下,几乎每个子类都要覆盖的函数/方法,就将它声明为 virtual;假如类层次很深,或子类很多,但某个函数/方法只被很少的子类覆盖,就将它声明为 dynamic。当然,具体就需要自己把握来选择了。
进入讨论组讨论。

上一篇:浅谈Object Pascal的指针 人气:336
下一篇:关于异常的使用心得 人气:403
浏览全部软件工程的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-10-10 企业网站智能管理系统(TZIMS) v6
2008-10-10 拓文asp.net网站内容管理系统 v6
2008-10-10 动网论坛PHP版 v2.0++ Build 081
2008-10-10 免费时代CMS v5.0
2008-10-10 wodig第四季中文DIGG社区 v4.1 b
2008-10-10 老Y文章管理系统 v2.2 bulid 081
2008-10-10 魔法盒动感相册 ASP+SQL版 v2.0
2008-10-10 Asoft签到管理系统 v3.0 Pack1
2008-10-10 哥特人音乐网潮流留言本 v1.1
2008-10-11 联系人分组工具 v1.1 中文破解版
2008-10-11 FaceMelter变脸 v2.0 汉化破解版
2008-10-11 PathTracker道路跟踪仪 v1.2 破解
2008-10-11 Rooms手机聊天室 v0.6.7 破解版
2008-10-11 RemoteDesktop远程桌面 v1.0 破解
2008-10-11 ProRemote远程调音台 v1.0.1 破解
2008-10-11 PicShare照片共享 v1.0.0 破解版
2008-10-11 Photogene照片编辑器 v1.5 汉化破
2008-10-11 WriteRoom共享文档 v1.0 破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | js/vbs加密 | md5加密 | 进制转换 | UTF-8 转换工具 | Html转换js | Html转换asp | Html转换php | Html转换perl
实用工具:汉字翻译拼音 | 拼音字典 | 符号对照表 | 个税计算 | 实时汇率查询换算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 | 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵
SEO対策 中国語教室 ホームページ作成