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”

  • 相关阅读:
    Node.js中的Buffer
    移动端页面弹出对话框效果Demo
    简单编写makefile文件,实现GCC4.9编译项目,增加boost库測试等等。。
    Windows下使用静态库
    将 Android* Bullet 物理引擎移植至英特尔® 架构
    Java读书笔记一(异常处理)
    设计模式
    Ignatius and the Princess III(杭电1028)(母函数)
    oracle树操作(select .. start with .. connect by .. prior)
    三期_day02_数据库表设计和开发准备工作
  • 原文地址:https://www.cnblogs.com/findumars/p/6143097.html
Copyright © 2011-2022 走看看