Delphi子类调用祖父类的虚函数
2024-09-01 00:11:03
因为看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”
最新文章
- BZOJ 1060: [ZJOI2007]时态同步
- php数组常见的几种遍历方法
- Struts2应用流程注解
- Python之SQLAlchemy学习
- threadlocal类
- Html5+css3+angularjs+jquery+webAPi 开发手机web(一)
- epoll 简单介绍及例子
- SQL Server中GO的使用方法(转)
- 格式化输出[part1/标准控制符]
- javascript中的闭包。
- HttpClient 设置代理方式
- ids &; hdmi 原理
- 【UVALive - 3713】Astronauts (2-SAT)
- angularjs 1.3 综合学习 (one way bind , ng-if , ng-switch , ng-messages, ng-form ,ng-model )
- Codeforces Round #256 (Div. 2)总结
- Python使用os.listdir()函数来获得目录中的内容
- mac 下常用命令备忘录
- vue px转换为rem
- .net向文件写入字符串流内存溢出的问题
- GAME PROGRAMM
热门文章
- Java易混点记录
- Fast-tracking approach for building routing topologies in fast-moving networks
- FontAwesome 图标
- Spring RestTemplate 专题
- Oracle 如何删除掉一个用户下的所有对象
- 脚本 启动/停止 jar包服务
- ESB (Enterprise Service Bus) 入门
- Qt5.8 下链接 Mysql 错误以及解决方法(无论 Mysql 是什么版本的,64 位 Qt 要用 64 位的 Mysql 驱动,32 位的 Qt 要用 32 位的Mysql 驱动)
- 绕过010Editor网络验证(用python做一个仿真http server真容易,就几行代码)
- 在WPF中减少逻辑与UI元素的耦合