【问题标题】:Static dispatch in PascalPascal 中的静态调度
【发布时间】:2020-07-09 03:04:15
【问题描述】:

我有一个简单的盒子类层次结构,如下所示:

type
  Box = object

    (* v := value; *)
    constructor Init(value: integer);

    (* WriteLn('this box contains a ', v); *)
    procedure Describe; virtual;

    protected
    var v: integer;

  end;

  SpecialBox = object(Box)

    (* implementation sets value and otherValue *)
    constructor Init(value: integer, otherValue: integer);

    (*  WriteLn('this special box contains ', v, ' and ', v2); *)
    procedure Describe; virtual;

    protected
    var v2: integer;

  end;

我省略了(琐碎的)实现,因为我不想用 Pascal 的冗长语法来混淆这个问题。无论如何,我有以下程序:

procedure printBox(box: Box); begin
  box.Describe;
end;

请注意,该过程使用静态分配的Box。对于像 C++ 这样的语言,我希望调用 box.Describe 静态链接到 Box 类中的方法。相反,我在控制台中看到的结果是

'this special box contains <the value of v> and <garbage because v2 is sliced off>'

因此我的问题是:Pascal(或特别是 FPC)在方法分派方面是否采用其他策略?

【问题讨论】:

  • 这是您在 C++ 中看到的经典切片。这是我们在 Delphi 中不使用object 的众多原因之一。你应该知道object 已经过时了几十年了。请改用class。另请注意,在派生类中,您需要使用override 来覆盖虚拟方法。最后,为什么要标记问题delphi,然后引用fpc?了解您使用的编码语言通常很重要。
  • 感谢您的评论。可悲的是,我就读的大学并不关心这已被弃用多年的事实。 :-) 我是专门询问这种奇怪行为的原因。关于语言的问题是我们曾经使用 Turbo Pascal,但为了学习 OOP,我们使用了 object-pascal(我认为?)。由于网络上的许多线程似乎混淆了 Pascal 和 Delphi,我想我可能会在这里找到可以通过使用 Delphi 标签来帮助我的人。
  • 了解您使用的语言非常重要。帕斯卡实际上有很多不同的口味。使用 fpc 有不同的模式。知道您使用哪种模式很重要。问题应标记为 freepascal。阅读有关对象切片的内容,这将使您直截了当。
  • 请注意 FreePascal 有几个语法差异。事实上,为了在 FreePascal 中成功编译 Delphi 代码,您需要启用 Delphi mode

标签: freepascal


【解决方案1】:

来自documentation

“对于对象,在后代对象中重新声明相同的方法,并使用关键字 virtual 来覆盖它就足够了”

这正是你正在做的。因此,尽管 Box 对象是静态分配的,但您的 Describe 方法是动态调度的(这两个不是 ra。如果您希望它静态调度,则不要使用虚拟方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    • 2015-08-15
    相关资源
    最近更新 更多