因为看Delphi书的时候,就产生了疑惑。老讲调用父类虚函数,但是万一需要调用祖父虚函数怎么办?
后来又经常在C++里看到,就更疑惑了

  1. type
  2. TA = class
  3. procedure ShowMsg; virtual;
  4. end;
  5.  
  6. TAClass = class of TA;
  7.  
  8. TB = class(TA)
  9. procedure ShowMsg; override;
  10. end;
  11.  
  12. TShowMsg = procedure of object;
  13.  
  14. TC = class(TB)
  15. private
  16. FGrandFatherShowMsg: TShowMsg;
  17. procedure ShowMsg; override;
  18. public
  19. constructor Create;
  20. end;
  21.  
  22. procedure TForm2.Button1Click(Sender: TObject);
  23. var
  24. C: TC;
  25. begin
  26. C := TC.Create;
  27. C.ShowMsg;
  28. C.Free;
  29. end;
  30.  
  31. { TC }
  32.  
  33. constructor TC.Create;
  34. var
  35. AMethod:TShowMsg;
  36. ACode: TMethod absolute AMethod;
  37. A: TA;
  38. begin
  39. inherited Create;
  40. A := TA.Create;
  41. FGrandFatherShowMsg := A.ShowMsg;
  42. AMethod:= FGrandFatherShowMsg;
  43. ACode.Data := Self;
  44. A.Free;
  45. end;
  46.  
  47. procedure TC.ShowMsg;
  48. begin
  49. FGrandFatherShowMsg;
  50. ShowMessage('TC');
  51. end;
  52.  
  53. { TA }
  54.  
  55. procedure TA.ShowMsg;
  56. begin
  57. ShowMessage('TA');
  58. end;
  59.  
  60. { TB }
  61.  
  62. procedure TB.ShowMsg;
  63. begin
  64. inherited;
  65. ShowMessage('TB');
  66. end;

利用了 Delphi 能够创建纯虚函数实例的特性
记录下了TA的函数地址
然后替换其Data的值为Self,然后在需要的时候再调用
利用了两点:TMethod和Delphi能够创建纯虚类实例
只是说万一纯虚的话,这个也好使

感谢 [长春]swish

----------------------------------------------------------

另一种办法:

  1. type
  2. TBase = class
  3. procedure Foo; virtual;
  4. end;
  5.  
  6. TAnsestor = class(TBase)
  7. procedure Foo; override;
  8. end;
  9.  
  10. TChild = class(TAnsestor)
  11. procedure Foo; override;
  12. procedure BaseFoo;
  13. end;
  14.  
  15. procedure TBase.Foo;
  16. begin
  17. ShowMessage('TBase');
  18. end;
  19.  
  20. procedure TAnsestor.Foo;
  21. begin
  22. ShowMessage('TAnsestor');
  23. end;
  24.  
  25. procedure TChild.Foo;
  26. begin
  27. ShowMessage('TChild');
  28. end;
  29.  
  30. type
  31. TFoo = procedure of object;
  32.  
  33. procedure TChild.BaseFoo;
  34. var
  35. Proc: TFoo;
  36.  
  37. begin
  38. TMethod(Proc).Code := @TBase.Foo; // Static address
  39. TMethod(Proc).Data := Self;
  40. Proc();
  41. end;
  42.  
  43. procedure TForm4.Button1Click(Sender: TObject);
  44. var
  45. Obj: TChild;
  46. Proc: TFoo;
  47.  
  48. begin
  49. Obj:= TChild.Create;
  50. Obj.BaseFoo;
  51. // or else
  52. TMethod(Proc).Code := @TBase.Foo; // Static address
  53. TMethod(Proc).Data := Obj;
  54. Proc();
  55.  
  56. Obj.Free;
  57. 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. 属性动画Property Animation

    ViewPropertyAnimation 使用方式:View.animate() 后跟 translationX() 等方法,动画会自动执行. 注意translationX实现是调用对应的set方法 ...

  2. Vuex的一个易错点

    好长时间不用Vuex,发现有些东西记模糊了. 在对Vuex进行模块化开发的时候, const store = new Vuex.Store({ modules: { a: moduleA, b: mo ...

  3. Spring MVC的RequestContextHolder使用误区 good

    JShop简介:jshop是一套使用Java语言开发的B2C网店系统,致力于为个人和中小企业提供免费.好用的网店系统. 项目主页:http://git.oschina.net/dinguangx/js ...

  4. 十分钟了解 spring cloud

    1 为什么需要服务发现 简单来说,服务化的核心就是将传统的一站式应用根据业务拆分成一个一个的服务,而微服务在这个基础上要更彻底地去耦合(不再共享DB.KV,去掉重量级ESB),并且强调DevOps和快 ...

  5. 判断软件的闲置时间(使用Application.OnMessage过滤所有键盘鼠标消息)

    GetLastInputInfo是检测系统输入的,应用到某个程序中不合适! 此问题有二种解法来监控输入消息: 1.用线程级HOOK,钩上MOUSEHOOK与KEYBOARDHOOK 2.在Applic ...

  6. sgu209:Areas(计算几何)

    意甲冠军: 给一些直.这架飞机被分成了很多这些线性块.每个块的需求面积封闭曲线图. 分析: ①我们应要求交点22的直线: ②每行上的交点的重排序,借此来离散一整行(正反两条边): ③对于连向一个点的几 ...

  7. 微信小程序 获取用户信息 encryptData解密 C#版本

    最近学习小程序开发,需要对encryptData解密,获取用户信息,官方源码没有C#版本,网上的资料比较杂,有的使用还有问题,下面贴一下自己亲试可以使用的一个源码 1.code 换取 session_ ...

  8. WPF中,怎样将XAML代码加载为相应的对象?

    原文:WPF中,怎样将XAML代码加载为相应的对象? 在前面"在WPF中,如何得到任何Object对象的XAML代码?"一文中,我介绍了使用System.Windows.Marku ...

  9. 怎样正确的理解和解决 ORA-01843:not a valid month

    今天码代码的时候遇到了这个问题,由于oracle用的比較少,所在查询了一下. 顿时傻眼,有非常多的贴子说是由于nls_date_language的问题,还要改会话级的NLS_DATE_LANGUAGE ...

  10. #748 – 获得按下时对应位置点的大小(Getting the Size of a Contact Point during Raw Touch)

    原文:#748 – 获得按下时对应位置点的大小(Getting the Size of a Contact Point during Raw Touch) 原文地址:https://wpf.2000t ...