为什么记录上不允许无参数构造函数?

时间:2017-09-02 08:39:54

标签: delphi

以下声明:

type
  TRec = record
    constructor Create;
  end;

产生此编译错误:

  

E2394记录类型不允许使用无参数构造函数

documentation相当无益的说明:

  

此错误或警告无法提供进一步的信息。

我的问题是为什么语言是这样设计的。这样做纯粹是为了echo the analogous restriction for C# structs吗?

language guide说:

  

使用默认的无参数构造函数自动构造记录,但必须显式构造类。由于记录具有默认的无参数构造函数,因此任何用户定义的记录构造函数都必须具有一个或多个参数。

但这没有多大意义。如果记录有默认构造函数,则无法通过RTTI找到它。即使有,为什么这意味着不可能添加另一个?您可以为课程这样做。

也许理由是如果允许我们定义自己的无参数构造函数,我们希望编译器自动调用它们。

注意:我了解您可以使用无参数静态类函数作为变通方法。实际上,我个人总是喜欢使用静态类函数而不是记录构造函数。但这不是问题的关键。我真正想知道的是为什么无参数构造函数不允许记录类型。

1 个答案:

答案 0 :(得分:4)

我不能给你一个确定的答案(只有编译器构建者可以),但我怀疑它与Delphi的.NET过去无关,而是与Delphi与C ++ Builder的关系。

正如cppreference所说:

  

默认构造函数是一个构造函数,可以不带参数调用(使用空参数列表定义,或者为每个参数提供默认参数)。

C ++允许无参数构造函数,这些无参数构造函数将成为C ++中的默认构造函数。在许多情况下调用默认构造函数,例如如果您只是声明:

Foo myFoo;

调用默认构造函数。这在Delphi中不会发生,但C ++程序员可能会期待它。同样,如果你这样做:

Foo elements[1000];

在每个元素上调用默认构造函数(我检查过)。这在Delphi中也不会发生,尽管C ++程序员可能会期待它。

其他暗示这是与C ++相关的:

  • 也不允许使用不同名称的构造函数(例如Init)。这似乎指向与C ++或C#的冲突,因为在两者中,构造函数都具有类或结构的名称,因此任何无参数构造函数都将映射到Foo()(在名为{{1}的结构或类中}。)
  • 也不允许使用仅包含默认参数的构造函数。这与仅具有默认参数的默认构造函数的cppreference描述相匹配。

总而言之,有些提示无参数构造函数(或只有默认参数的构造函数)与C ++(即C ++ Builder)冲突,这就是为什么它们不被允许的原因。

请注意,这不是由与C ++的差异引起的唯一限制:例如在Delphi中,你不能将整数转换为浮点类型和从浮点类型转换整数,因为在C和C ++中,这会导致转换,而在Delphi中,它只会导致对位的重新解释。为了不混淆从C或C ++进入Delphi的人,对浮点类型进行了强制转换。可能还有更多。