虚拟方法跳过父类继承调用祖父类的代码

TGrandpaObject = class
public
  procedure AVirtualMethod; virtual;
end;

TParentObject = class(TGrandpaObject)
public
  procedure AVirtualMethod; override;
end;

TCurrentObject = class(TParentObject)
public
  procedure AVirtualMethod; override;
end;

TCurrentObject的AVirtualMethod虚拟方法不希望调用父类TParentObject的AVirtualMethod方法的实现代码,而要直接继承调用祖父类TGrandpaObject的AVirtualMethod方法代码。
类的继承体系中,在VMT中,子类的VMT完全包含父类的VMT,而自身的虚拟方法则是附着在VMT父类虚拟方法表的后面,也就是说子类虚拟方法和父类虚拟方法的相对偏移量是相同的,只是子类的虚拟方法有覆盖时,子类VMT中该虚拟方法的地址被覆盖啦。因此,要跳过父类的虚拟方法而直接调用祖父类的虚拟方法代码,那么只要通过VMT的虚拟方法的相对偏移量找到祖父类的虚拟方法地址,然后调用即可。
procedure TCurrentObject.AVirtualMethod;
begin
  asm
        MOV     EDX,VMTOFFSET AVirtualMethod // 虚拟方法VMT偏移量
        MOV     EAX,Self                     // 对象实例 => EAX
        MOV     ECX,[EAX]                    // 类VMT => ECX
        MOV     ECX,[ECX].vmtParent
        MOV     ECX,[ECX]                    // 父类VMT => ECX
        MOV     ECX,[ECX].vmtParent
        MOV     ECX,[ECX]                    // 祖父类VMT => ECX
        MOV     ECX,[ECX+EDX]                // 祖父类虚拟方法地址 => ECX
        CALL    ECX                          // 方法调用
  end;
end;

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

coolbaby

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值