【问题标题】:Delphi Tdictionary inheritanceDelphi字典继承
【发布时间】:2016-11-08 17:14:09
【问题描述】:

我尝试从 Tdictionary 继承,但不知何故默认比较器丢失了。这就是我本质上所做的:

type
  TinpVar = class
  end;
  TinputVars = class(Tdictionary<string,TinpVar>)
  end;
  TLVRvars = class(TinputVars)
    constructor create;
  end;

 constructor TLVRvars.create;
 begin
   inherited;
 end;

 var LVRvars : TLVRvars;

 begin
   LVRvars:=TLVRvars.create;

通过这种结构,我在向 LVRvars 添加键/值对时得到了一个 AV。最终我发现可以通过将继承类的构造函数改为

constructor TLVRvars.create;
begin
  inherited create;
end;

我不明白为什么我必须这样做。虽然我的问题解决了,但我还是想知道。

【问题讨论】:

  • 你之前有没有构造函数?

标签: delphi generics inheritance


【解决方案1】:

在你的构造函数中

 inherited;

使用与构造函数相同的参数列表调用构造函数。您的构造函数没有参数,因此inherited 调用TObject 中的无操作构造函数。您不仅丢失了比较器,而且您的实例也缺少构建过程中的其余必要步骤。

当你用

替换它时
inherited Create;

编译器改为执行正常的方法解析。它查找类祖先列表并调用它可以调用的第一个方法。在这种情况下,这是:

constructor Create(ACapacity: Integer = 0); overload;

因此您的实例已正确创建。

文档在这里:http://docwiki.embarcadero.com/RADStudio/en/Methods#Inherited

主要摘录如下:

如果inherited后面跟着一个成员的名字,代表一个普通的方法调用

当inherited后面没有标识符时,它指的是被继承的 与封闭方法同名的方法,或者,如果封闭方法 方法是一个消息处理程序,以继承的消息处理程序为 相同的消息。在这种情况下,inherited 没有显式参数, 但传递给继承的方法相同的参数 调用了封闭方法。例如:

inherited;

在构造函数的实现中经常出现。它调用 继承构造函数,其参数与传递给 后代。

这很奇怪不是吗。从表面上看,调用不同的方法似乎令人惊讶。关键点是简单的inherited 导致参数列表的精确匹配。而且你的方法没有参数。

另一方面,inherited Create 是标准方法调用。在后一种情况下,您最终会使用该参数的默认值调用带有一个参数的方法。因此,虽然看起来您正在调用无参数构造函数,但实际上并非如此。您正在传递一个参数 ACapacity 和一个值 0

【讨论】:

  • 强调默认参数的危险。在这种情况下,看起来完全等价的代码:inherited;(最终)调用默认的无参数 ctor Create vs inherited Create; 似乎显式调用继承的无参数ctor Create 但实际上解析为具有 default 参数的 ctor。很好的收获。
【解决方案2】:

比较器是一个需要自己创建的对象。如果您的后代类中没有构造函数,我希望创建默认构造函数,因为您将隐式调用继承的构造函数。如果您创建自己的构造函数,则应始终调用继承的 Create(在我看来)以允许祖先完成其工作 - 在这种情况下创建默认比较器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-04
    • 2018-02-09
    • 2010-12-08
    • 2020-12-27
    • 2016-12-27
    • 1970-01-01
    • 2017-09-26
    • 2013-02-06
    相关资源
    最近更新 更多