因为看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”

Delphi子类调用祖父类的虚函数的更多相关文章

  1. C++ 类中有虚函数(虚函数表)时 内存分布

    虚函数表 对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的.简称为V-Table.在这个表中,主是要一个类的虚函数的地址表 ...

  2. 关于MFC中重载函数是否调用基类相对应函数的问题

    在重载CDialog的OnInitDialog()函数的时候,在首行会添加一句:CDialongEx::OnInitDialog();语句,这是为什么呢?什么时候添加,什么时候不添加? 实际上,我们在 ...

  3. C++基类、派生类、虚函数的几个知识点

    1.尽管派生类中含有基类继承来的成员,但派生类初始化这部分变量需要调用基类的构造函数. class A { private: int x; virtual void f(){cout<<& ...

  4. C++ - 虚基类、虚函数与纯虚函数

    虚基类       在说明其作用前先看一段代码 class A{public:    int iValue;}; class B:public A{public:    void bPrintf(){ ...

  5. C++ //多态 //静态多态:函数重载 和 运算符重载 属于静态多态 ,复用函数名 //动态多态:派生类和虚函数实现运行时多态

    1 //多态 2 //静态多态:函数重载 和 运算符重载 属于静态多态 ,复用函数名 3 //动态多态:派生类和虚函数实现运行时多态 4 5 //静态多态和动态多态的区别 6 //静态多态的函数地址早 ...

  6. C++ - 类的虚函数\虚继承所占的空间

    类的虚函数\虚继承所占的空间 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24236469 char占用一个字节, 但不满足4的 ...

  7. C++学习笔记第三天:类、虚函数、双冒号

    类 class Box { public: double length; // 盒子的长度 double breadth; // 盒子的宽度 double height; // 盒子的高度 }; 类成 ...

  8. 获取C++类成员虚函数地址

    1.GCC平台 GCC平台获取C++成员虚函数地址可使用如下方法[1]: class Base{ int i; public: virtual void f1(){ cout<<" ...

  9. C#调用c++类的导出函数

    C# 需要调用C++东西,但是有不想做成COM,就只好先导出类中的函数处理. 不能直接调用,需单独导出函数 参考:http://blog.csdn.net/cartzhang/article/deta ...

随机推荐

  1. hbase 2.0.2 分布式安装配置/jar包替换

    环境 zk: 3.4.10 hadoop 2.7.7 jdk8 hbase 2.0.2 三台已安装配置好的hadoop002,hadoop003,hadoop004 1.上传并解压hbase-2.1. ...

  2. spring boot jar包 linux 部署

    前提: jar包路径:/usr/local/lib/app/app.jar 1.首先先用vi创建文件 命令: cd /usr/local/lib/app/vi app-start.sh 2.在文件ap ...

  3. 基于RDP瘦客户机协议的简要说明

    **************************************************************************************************** ...

  4. Qt 元对象系统(Meta-Object System)(不管是否使用信号槽,都推荐使用)

    Qt 元对象系统(Meta-Object System) Qt的元对象系统基于如下三件事情: 类:QObject,为所有需要利用原对象系统的对象提供了一个基类. 宏:Q_OBJECT,通常可以声明在类 ...

  5. WPF 小矢量图 : 主页,返回,加,减,文字按钮,左移,右移

    原文:WPF 小矢量图 : 主页,返回,加,减,文字按钮,左移,右移 代码:: <UserControl x:Class="SQ.TestPage" xmlns=" ...

  6. 实现在 .net 中使用 HttpClient 下载文件时显示进度

    在 .net framework 中,要实现下载文件并显示进度的话,最简单的做法是使用 WebClient 类.订阅 DownloadProgressChanged 事件就行了. 但是很可惜,WebC ...

  7. Android中集成支付宝

    手机的在线支付,被认为是2012年最看好的功能,我个人认为这也是移动互联网较传统互联网将会大放光彩的一个功能. 人人有手机,人人携带手机,花钱买东西,不再需要取钱付现,不再需要回家上网银,想买什么,扫 ...

  8. matlab 高级函数

    2*randn(sz):0 均值,方差为 4(variance), standard deviation:标准差为 2: numel():returns the # of elements: nume ...

  9. WPF ListView 居中显示

    原文:WPF ListView 居中显示 今天遇到的问题: 方法1:设置GridViewColumn的ActualWidth <ListView > <ListView.View&g ...

  10. debian8 root无法远程登录解决办法

    改一下root 密码,应该就能本地登录了. 改/etc/ssh/sshd.conf,然后重启ssh就能远程登录了:PermitRootLogin yesPermitEmptyPasswords no