【问题标题】:How can I invoke the `Inherited` ancestor method in overridden virtual functions?如何在重写的虚函数中调用“继承”祖先方法?
【发布时间】:2008-12-04 14:53:46
【问题描述】:

这行得通:

constructor TMyObj.Create;
begin
 inherited;
end;

为什么这也不起作用?

function TMyObjEx.Import(CONST FileName: string; CONST x, y, z: Integer): string;
begin
 result:= inherited; // Import(FileName, x, y, z);  <--- Compiler says: "incompatible types"
 //do other stuff here
end;

TMyObjEx 的声明是这样的:

TYPE

TMyObj = class(TChObj)
      private
      protected
      public
       function Import (CONST FileName: string; CONST x, y, z: Integer): string; virtual;     
     end;

TMyObjEx= class(TMyObj)
          private
          protected
          public
           function Import(CONST FileName: string; CONST x, y, z: Integer): string; override;   
         end;

【问题讨论】:

  • Stackoverflow 应该有另一个类别“非建设性批评”,提问者批评伪装成问题的语言、库或工具。

标签: delphi


【解决方案1】:

这是正确答案。

执行此操作的正确方法如上所述:

function TMyObjEx.Import(CONST FileName: string; CONST x, y, z: Integer): string;
begin
 result:= inherited Import(FileName, x, y, z); 
 //do other stuff here
end;

语言不支持您想要的方式。

所以最终回答了你的问题“为什么这也不起作用?”是因为这不是语言的设计方式。

【讨论】:

  • 好吧,我知道,但为什么呢? ;) (说真的,我会对为什么这适用于过程但不适用于函数的低级技术原因感兴趣)
  • 按照您尝试的方式进行操作需要更高级别的“假设”。
  • 但这是一个自然的假设。它适用于所有东西,除了函数——当你查看文档时,它指的是“方法”,对我来说,这意味着函数、过程、构造函数和析构函数。
  • 这个答案帮助我摆脱了困境。仅继承给了我“不兼容的类型”错误,继承了 FunctionName 它可以工作。谢谢
  • 你不得不承认这是一个糟糕的语言设计,因为它很容易陷入错误。
【解决方案2】:

当您需要方法的结果时,自动传递参数不起作用。需要填写方法名和参数,对不起。

【讨论】:

  • 你的回答很有帮助,为什么抱歉 ;)
【解决方案3】:

至于为什么不支持,Hallvard 几年前在他的博客中写了一个plausible explanation

关于“继承”的一个警告;语法是函数不支持它。为了 函数必须使用显式语法,包括方法名称和任何参数。 例如:

[一些代码]

这可能看起来像是 Delphi 语言设计中的疏忽,但我认为它是 商榷。其背后的基本原理可能是,如果 TMyClass.MethodC 是抽象的(或 将来抽象),后代类中的结果分配将是 删除,因此 Result 突然具有未定义的值。这肯定会引起微妙的 错误。

【讨论】:

  • 这是一个“合理”的解释吗?无论您是显式调用继承的抽象函数,还是隐式调用,继承的抽象函数都没有返回(没有调用,没有返回),因此即使它可能出现,仍然没有(实际上)分配结果在被覆盖的函数中初始化。
  • 因为可以调用继承;如果祖先中没有匹配的函数,则简单地忽略该语句。但是如果你使用继承的 Method();并且祖先类中没有匹配的方法会导致编译时错误。基于这一点,人们会期望 Result := inherit;如果没有要调用的继承方法,则将被忽略。但这会使 Result 未分配。不调用过程没有副作用,不调用函数也会删除赋值。
【解决方案4】:

起初我以为如果你对函数的结果不感兴趣,你可以使用inherited,但事实并非如此。调用继承的函数方法需要方法名和参数。就是那样子。如果您传递的参数与当前方法接收的参数不同,或者您正在调用完全不同的方法,您还需要提及方法名称。

【讨论】:

    【解决方案5】:

    似乎 Delphi 文档还有另一个黑洞……(哦哦哦,有什么好消息?)

    我的测试表明 use inherited 关键字在它仅适用于 构造函数、析构函数和过程 方法之后没有任何内容。在 Function 方法上它不起作用ATALL

    但是,我从来没有检测到它,因为我有完全调用继承方法的习惯,即使我不需要它(动机:能够使用 Ctrl+左键单击 on并且无需调试即可更轻松地遵循代码流程)。

    【讨论】:

    • 在重载覆盖的情况下,它也是一个有用的安全检查+平衡,以确保您确实调用了您真正想要的继承重载。 9/10 它是直接继承的方法,但是有十分之一的人会抓住你...... :)
    • @Deltics,同意。花费 90% 时间的总是最后 10% ;-)
    猜你喜欢
    • 2011-06-07
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 2016-07-12
    相关资源
    最近更新 更多