因为看Delphi书的时候,就产生了疑惑。老讲调用父类虚函数,但是万一需要调用祖父虚函数怎么办?
后来又经常在C++里看到,就更疑惑了

type
TA = class
procedure ShowMsg; virtual;
end; TAClass = class of TA; TB = class(TA)
procedure ShowMsg; override;
end; TShowMsg = procedure of object; TC = class(TB)
private
FGrandFatherShowMsg: TShowMsg;
procedure ShowMsg; override;
public
constructor Create;
end; procedure TForm2.Button1Click(Sender: TObject);
var
C: TC;
begin
C := TC.Create;
C.ShowMsg;
C.Free;
end; { TC } constructor TC.Create;
var
AMethod:TShowMsg;
ACode: TMethod absolute AMethod;
A: TA;
begin
inherited Create;
A := TA.Create;
FGrandFatherShowMsg := A.ShowMsg;
AMethod:= FGrandFatherShowMsg;
ACode.Data := Self;
A.Free;
end; procedure TC.ShowMsg;
begin
FGrandFatherShowMsg;
ShowMessage('TC');
end; { TA } procedure TA.ShowMsg;
begin
ShowMessage('TA');
end; { TB } procedure TB.ShowMsg;
begin
inherited;
ShowMessage('TB');
end;

利用了 Delphi 能够创建纯虚函数实例的特性
记录下了TA的函数地址
然后替换其Data的值为Self,然后在需要的时候再调用
利用了两点:TMethod和Delphi能够创建纯虚类实例
只是说万一纯虚的话,这个也好使

感谢 [长春]swish

----------------------------------------------------------

另一种办法:

type
TBase = class
procedure Foo; virtual;
end; TAnsestor = class(TBase)
procedure Foo; override;
end; TChild = class(TAnsestor)
procedure Foo; override;
procedure BaseFoo;
end; procedure TBase.Foo;
begin
ShowMessage('TBase');
end; procedure TAnsestor.Foo;
begin
ShowMessage('TAnsestor');
end; procedure TChild.Foo;
begin
ShowMessage('TChild');
end; type
TFoo = procedure of object; procedure TChild.BaseFoo;
var
Proc: TFoo; begin
TMethod(Proc).Code := @TBase.Foo; // Static address
TMethod(Proc).Data := Self;
Proc();
end; procedure TForm4.Button1Click(Sender: TObject);
var
Obj: TChild;
Proc: TFoo; begin
Obj:= TChild.Create;
Obj.BaseFoo;
// or else
TMethod(Proc).Code := @TBase.Foo; // Static address
TMethod(Proc).Data := Obj;
Proc(); Obj.Free;
end;

http://stackoverflow.com/questions/4662744/delphi-how-to-call-inherited-inherited-ancestor-on-a-virtual-method

诀窍是搜索关键字“delphi inherited super parent”

最新文章

  1. BZOJ 1060: [ZJOI2007]时态同步
  2. php数组常见的几种遍历方法
  3. Struts2应用流程注解
  4. Python之SQLAlchemy学习
  5. threadlocal类
  6. Html5+css3+angularjs+jquery+webAPi 开发手机web(一)
  7. epoll 简单介绍及例子
  8. SQL Server中GO的使用方法(转)
  9. 格式化输出[part1/标准控制符]
  10. javascript中的闭包。
  11. HttpClient 设置代理方式
  12. ids & hdmi 原理
  13. 【UVALive - 3713】Astronauts (2-SAT)
  14. angularjs 1.3 综合学习 (one way bind , ng-if , ng-switch , ng-messages, ng-form ,ng-model )
  15. Codeforces Round #256 (Div. 2)总结
  16. Python使用os.listdir()函数来获得目录中的内容
  17. mac 下常用命令备忘录
  18. vue px转换为rem
  19. .net向文件写入字符串流内存溢出的问题
  20. GAME PROGRAMM

热门文章

  1. Java易混点记录
  2. Fast-tracking approach for building routing topologies in fast-moving networks
  3. FontAwesome 图标
  4. Spring RestTemplate 专题
  5. Oracle 如何删除掉一个用户下的所有对象
  6. 脚本 启动/停止 jar包服务
  7. ESB (Enterprise Service Bus) 入门
  8. Qt5.8 下链接 Mysql 错误以及解决方法(无论 Mysql 是什么版本的,64 位 Qt 要用 64 位的 Mysql 驱动,32 位的 Qt 要用 32 位的Mysql 驱动)
  9. 绕过010Editor网络验证(用python做一个仿真http server真容易,就几行代码)
  10. 在WPF中减少逻辑与UI元素的耦合