【发布时间】:2016-07-08 08:54:51
【问题描述】:
编译以下代码时出现错误:
TOmniParallelSimplePooledLoop = class(TOmniParallelSimpleLoop)
procedure Execute(loopBody: TOmniIteratorSimpleSimpleDelegate); overload; override;
[dcc64 错误] OtlParallel.pas(846): E2170 无法覆盖非虚拟方法
如果我将祖先方法设为虚拟,那么错误就会消失。
然而祖先方法声明在:
IOmniParallelSimpleLoop
...
procedure Execute(loopBody: TOmniIteratorSimpleSimpleDelegate); overload;
将TOmniParallelSimpleLoop 中的基方法从非虚拟重新声明为虚拟会改变基类型,还是该方法一开始就已经是虚拟的(因为它是接口方法的实现)?
换句话说:当接口方法从非虚拟变为虚拟时,编译器会输出不同的代码吗?
用于重新创建错误的基本 MSVC
program Project70;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
type
I1 = interface
procedure DoSomething;
end;
T1 = class(TInterfacedObject, I1)
procedure DoSomething;
end;
T2 = class(T1)
procedure DoSomething; override;
end;
procedure T1.DoSomething;
begin
WriteLn('parent');
end;
procedure T2.DoSomething;
begin
Writeln('Child');
end;
begin
end.
【问题讨论】:
-
您应该问的真正问题是 Delphi 如何编译 T1。如果 T1.DoSomething 是静态的。所有的 COM 书籍都声明 COM = VMT。那么 T1.DoSomething 是如何进入 VMT 的呢?我想这就是你的困惑发生的地方。因为它不是用于虚拟方法调用的类 VMT,而是 VMT 映射方法,无论是静态、虚拟还是动态,所以接口知道要调用什么方法……这里有一篇很棒的文章,向您展示了如何在没有对象的情况下实现接口. sergworks.wordpress.com/2012/04/01/interfaces-without-objects
标签: class delphi interface virtual