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

来源:互联网 发布:电子配音软件下载 编辑:程序博客网 时间:2024/04/29 18:55

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;

原创粉丝点击