I try to inherit from Tdictionary and somehow the default comparer is lost. This is what I do in essence:
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;
With this construction I get an AV when adding a key/value pair to LVRvars. Eventually I found that this can be prevented by changing the constructor of the inherited class to
constructor TLVRvars.create;
begin
inherited create;
end;
I do not understand why I have to do that. Although my problem is solved, I would still like to know.
In your constructor
inherited;
calls the constructor with identical parameter list to your constructor. Your constructor has no parameters, and so inherited
calls the do nothing constructor in TObject
. Not only have you lost your comparer, but your instance is missing the rest of the necessary steps in construction.
When you replace it with
inherited Create;
the compiler instead performs normal method resolution. It looks up the class ancestor list and calls the first method which it can. In that case this is:
constructor Create(ACapacity: Integer = 0); overload;
Hence your instance is properly created.
The documentation is here: http://docwiki.embarcadero.com/RADStudio/en/Methods#Inherited
Key excerpts are:
If inherited is followed by the name of a member, it represents a normal method call
and
When inherited has no identifier after it, it refers to the inherited method with the same name as the enclosing method or, if the enclosing method is a message handler, to the inherited message handler for the same message. In this case, inherited takes no explicit parameters, but passes to the inherited method the same parameters with which the enclosing method was called. For example:
inherited;
occurs frequently in the implementation of constructors. It calls the inherited constructor with the same parameters that were passed to the descendant.
It's pretty weird isn't it. On the face of it, it seems astonishing that different methods are called. The key point though is that plain inherited
leads to exact matching of parameter lists. And your method has no parameters.
On the other hand inherited Create
is a standard method call. In that latter case, you end up calling a method with one parameter, using the default value for that parameter. So whilst it looks like you are calling a parameterless constructor you are not. You are passing one parameter, ACapacity
, and a value of 0
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With