zoukankan      html  css  js  c++  java
  • 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”

  • 相关阅读:
    帧间编码的预测自适应量化系数扫描排序
    调试vp8编码和解码程序
    WPF学习——制作一个简单的录入界面(2):用C#编程实现所有控件的功能
    自适应变异引用(AWR)方法(an adaptive warped reference (AWR) method )
    vp8编解码调试(环境vs2005)
    加油
    开始工作blog了
    vs2010编译vp8
    WPF学习——制作一个简单的录入界面(1): 添加需要的控件
    JPEG编码
  • 原文地址:https://www.cnblogs.com/findumars/p/6143097.html
Copyright © 2011-2022 走看看