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

Posted 朝闻道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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”

 

以上是关于Delphi子类调用祖父类的虚函数的主要内容,如果未能解决你的问题,请参考以下文章

如何能避免在调用子类对象的虚函数时调用父类的虚函数呢?

C++子类如何调父类的虚函数

关于C++的虚函数在父类的内部调用

C++中,子类会继承父类的虚函数表!对于父类的析构函数(虚函数) 也会继承吗?

C++ 中,类的继承:父类当使用虚函数时候,子类对该函数进行重写的话,属于子类成员函数对虚函数的覆盖!

请教,父类中如何调用子类中的虚函数