Delphi TDictionary继承问题

16

我试图从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;

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


你之前有构造函数吗? - Dsm
2个回答

21

在你的构造函数中

 inherited;

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

当您将其替换为

inherited Create;

编译器会执行常规的方法解析,查找类的祖先列表并调用它能找到的第一个方法。如果这样,那么这是:

相反地,编译器会执行常规的方法解析,查找类的祖先列表并调用它能找到的第一个方法。如果这样,那么这是:

constructor Create(ACapacity: Integer = 0); overload;
因此,您的实例已正确创建。
文档在这里:http://docwiki.embarcadero.com/RADStudio/en/Methods#Inherited 重要摘录如下:

如果inherited后跟成员的名称,则表示普通方法调用。

并且

当inherited后没有标识符时,它引用与封闭方法同名的继承方法,或者如果封闭方法是消息处理程序,则引用与相同消息的继承消息处理程序。 在这种情况下,inherited不需要显式参数,但会将与调用封闭方法时相同的参数传递给继承方法。例如:

inherited;

在构造函数的实现中经常出现这种情况。它使用与派生类传递的相同参数调用继承的构造函数。


3
强调默认参数的危险性。在这种情况下,看起来完全相同的代码:inherited; 实际上调用了无参构造函数Create,而 inherited Create; 表面上 显式地调用继承的无参构造函数Create,但实际上解析为一个带有默认参数的构造函数。注意到了这个问题是很好的。 - Deltics

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接