我尝试继承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;
我不明白为什么要这样做。虽然我的问题已经解决了,但我仍然想知道。
答案 0 :(得分:21)
在你的构造函数
中 inherited;
使用与构造函数相同的参数列表调用构造函数。您的构造函数没有参数,因此inherited
调用TObject
中的do nothing构造函数。您不仅丢失了比较器,而且您的实例缺少构建中的其余必要步骤。
用
替换它时inherited Create;
编译器改为执行常规方法解析。它查找类祖先列表并调用它可以的第一个方法。在这种情况下,这是:
constructor Create(ACapacity: Integer = 0); overload;
因此,您的实例已正确创建。
文档在这里:http://docwiki.embarcadero.com/RADStudio/en/Methods#Inherited
主要摘录如下:
如果继承后跟成员名称,则表示正常的方法调用
和
当继承后没有标识符时,它指的是继承的 与封闭方法同名的方法,或者如果是封闭的方法 方法是一个消息处理程序,用于继承的消息处理程序 同样的消息。在这种情况下,inherited没有显式参数, 但传递给继承的方法与之相同的参数 封闭方法被称为。例如:
inherited;
在构造函数的实现中经常发生。它叫做 继承的构造函数具有传递给的相同参数 后代。
它很奇怪不是。从表面上看,调用不同的方法似乎令人惊讶。关键点是普通inherited
导致参数列表的精确匹配。而且你的方法没有参数。
另一方面,inherited Create
是标准方法调用。在后一种情况下,您最终使用一个参数调用方法,使用该参数的默认值。因此,虽然看起来你正在调用无参数构造函数,但事实并非如此。您传递的参数为ACapacity
,值为0
。
答案 1 :(得分:-2)
比较器是一个需要自己创建的对象。如果你的后代类中没有构造函数,我希望创建默认构造函数,因为你将隐式调用继承的构造函数。如果您创建自己的构造函数,则应始终调用继承的Create(在我看来)以允许祖先执行其工作 - 在这种情况下创建默认比较器。