Delphi子类调用祖父类的虚函数

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

时间: 2024-08-08 01:29:23

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

转 理解虚基类、虚函数与纯虚函数的概念

原文地址:理解虚基类.虚函数与纯虚函数的概念 引言 一直以来都没有写过一篇关于概念性的文章,因为我觉得这些概念性的东西书本上都有并且说的也很详细写来也无用,今天突发奇想想写 一写,下面就和大家讨论一下虚基类.虚函数与纯虚函数,一看名字就让人很容易觉得混乱.不过不要紧待看完本文后你就会理解了. 正文 虚基类        在说明其作用前先看一段代码 class A { public:     int iValue; }; class B:public A { public:     void bP

理解虚基类、虚函数与纯虚函数的概念

总结 虚基类     1, 一个类可以在一个类族中既被用作虚基类,也被用作非虚基类.     2, 在派生类的对象中,同名的虚基类只产生一个虚基类子对象,而某个非虚基类产生各自的子对象.     3, 虚基类子对象是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的.     4, 最派生类是指在继承结构中建立对象时所指定的类.     5, 派生类的构造函数的成员初始化列表中必须列出对虚基类构造函数的调用:如果未列出,则表示使用该虚基类的缺省构造函数.     6, 从虚基类直接或间接派

【C/C++学院】0825-类模板/final_override/类模板与普通类的派生类模板虚函数抽象模板类/类模板友元/位运算算法以及类声明/Rtti 实时类型检测/高级new创建/类以及函数包装器

类模板 类模板多个类型默认类型简单数组模板 #pragma once template <class T=int>//类模板可以有一个默认的值 class myArray { public: myArray(); ~myArray(); }; #include "myArray.h" template <class T=int>//每一个函数都需要加上一个默认的值 myArray<T>::myArray() //类模板成员函数在外部,需要加载类型初始

面向对象程序设计——概述,定义基类和派生类,虚函数

一.OOP:概述 面向对象程序设计的核心思想是数据抽象.继承和动态绑定.通过使用数据抽象,我们可以将类的接口和实现分离:使用继承,可以定义相似的类型并对其相似关系建模:使用动态绑定,可以在一定程度上忽略相似类型的区别,而以统一的方式使用它们的对象. 1)继承 通过继承联系在一起的类构成一种层次关系.通常在层次关系的根部有一个基类,其他类则直接或间接地从基类继承而来,这些继承得到的类称为派生类.基类负责定义在层次关系中所有类共同拥有的成员,而每个派生类定义各自的成员. 在C++语言中,基类将类型相

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

类的虚函数\虚继承所占的空间 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24236469 char占用一个字节, 但不满足4的倍数时, 会进行数据对齐, 使用4的倍数的字节(byte). GCC: GCC中, 不管是虚函数还是虚继承, 都须要将指针存储在虚函数表(virtual function table), 占用4个字节. 继承会继承基类的数据, 和虚函数表, 即继承基类的空间. 代码: /* * test.cpp *

PHPCMS调用form类编辑器editor函数动态上传图片附件

http://w3note.com/web/49.html phpcms v9的系统类库有一个表单类,它封装了表单的一些组件,如编辑器.图片上传.时间选择器.模板选 择器等,更详细请参考form.class.php.有了这些组件,在对phpcms v9进行二次开发时,更加省时省心.我们要做的就是如何把这些工具调出来使用.调用方法总共有两种. 一.视图调用法这种方法最简单,但有局限性.在后台的模型定义字段时,选择表单的类型就会生成相应的表单类型. 二.代码调用法这种方法比较灵活,走出了内容模块的限

派生表中第一个基类没有虚函数,派生类存在虚函数时的内存布局

单继承的例子: #include <iostream> using namespace std; class A { public: A() { a = 1; ch = 'a'; //ASCII码97 } private: int a; char ch; }; class C : public A { public: C() { c = 3; } virtual void print() { cout << "C" << endl; } privat

父类指针指向子类实例:同名非虚函数

场景描述:如果父类指针指向子类的实例,并且调用的函数是一个子类和父类同名的函数,并且这个函数没有被定义为虚函数,肯定无法通过父类指针调用子类的接口.测试代码如下: class CFather{ public:      void Display()     {         cout<<"Father display"<<endl;     } }; class CSon:public CFather { public:      void Display()

获取类中虚函数地址

// CMemory.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <IOSTREAM> using namespace std; class Base { public: virtual void f() { cout << "Base::f" << endl; } virtual void g