网站大量收购闲置独家精品文档,联系QQ:2885784924

访问祖先类的虚方法.docx

  1. 1、本文档共6页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
访问祖先类的虚方法 访问祖先类的虚方法 问题提出在子类覆盖的虚方法中,可以用 问题提出 在子类覆盖的虚方法中,可以用inherited 调用父类的实现,但有时候我们并不需要父类的实现,而是想跃过父类直接调用祖先类的方法。 举个例子,假设有三个类,实现如下: type TClassA = class procedure Proc; virtual; end; TClassB = class(TClassA) procedure Proc; override; end; TClassC = class(TClassB) procedure Proc; override; end; implementation procedure TClassA.Proc; begin ShowMessage(Proc of class A); end; procedure TClassB.Proc; begin ShowMessage(Proc of class B); end; procedure TClassC.Proc; begin ShowMessage(Proc of class C); end; 用如下代码调用虚方法 Proc: var C: TClassA; begin C := TClassC.Create; C.Proc; C.Free; C.Proc; C.Free; end; 我们知道最终调用的是 TClassC.Proc;如果在 TClassC.Proc 中加上 Inherited, 则 TClassB.Proc 可以得到调用;但是现在,若想在 TClassC.Proc 中直接调用TClassA.Proc,该怎么办呢? 解决之道 解决之道 如果是 C++,只需要这样写:TClassC::Proc。 在 Delphi 却没有办法做到,Delphi 不允许我们跃级调用祖先类的方法。尽管如此,还是能从另一个角度来寻求解决的办法。 解决之道就是 VMT,每一个类就是一个指向 VMT 的指针,而 VMT 的作用其实就是用来保存虚方法的。在 VMT 的正方向上,列着从祖先类起的所有虚方法,只需要偏移 TClassA 的 VMT 到 Proc,然后调用之即可。 来看看这个问题是怎么得解决的: procedure TClassC.Proc; type TProc = procedure of object; var M: TMethod; begin M.Code := PPointer(TClassA)^; M.Data := Self; TProc(M)(); ShowMessage(Proc of class C); end; 执行一次调用,可以看到先弹出:Proc of class A;然后弹出:Proc of class C。 这说明 TClassA.Proc 在 TClassC.Proc 中被调用到了。 请注意上面的代码,TClassA 的 VMT 上的第 0 偏移就是 Proc 的地址,而TClassA 继承自 TObject,TObject 本身也有一些虚方法的,比如 AfterConstruction,那么这些是存放在哪里呢? 秘密就在 VMT 的负偏移上,在 System 单元中声明了虚表的结构偏移,在负方向上有 AfterConstruction 的进入点。需要指出的是,System 单元中声明了结构偏移正方向的几个已经过时了,第 0 偏移(vmtQueryInterface)不是存放QueryInterface,而是存放第一个虚方法(除 TObject 外)。 下面是从帮助上拷下来的 VMT 布局: Offset Type Description -76 Pointer pointer to virtual method table (or nil) -72 Pointer pointer to interface table (or nil) -68 Pointer pointer to Automation information table (or nil) -64 Pointer pointer to instance initialization table (or nil) -60 -60 Pointer pointer to type information table (or nil) -56 Pointer pointer to field definition table (or nil) -52 Pointer pointer to method definition table (or nil) -48 Pointer pointer to dynamic method table (o

文档评论(0)

tianya189 + 关注
官方认证
内容提供者

该用户很懒,什么也没介绍

认证主体阳新县融易互联网技术工作室
IP属地湖北
统一社会信用代码/组织机构代码
92420222MA4ELHM75D

1亿VIP精品文档

相关文档