Наследование Delphi Tdictionary

Я пытаюсь наследовать от 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;

При этой конструкции я получаю AV при добавлении пары ключ/значение в LVRvars. В конце концов я обнаружил, что это можно предотвратить, изменив конструктор унаследованного класса на

constructor TLVRvars.create;
begin
  inherited create;
end;

Я не понимаю, почему я должен это делать. Хотя моя проблема решена, мне все равно хотелось бы знать.

Ответы

Ответ 1

В вашем конструкторе

 inherited;

вызывает конструктор с идентичным списком параметров для вашего конструктора. У вашего конструктора нет параметров, поэтому inherited вызывает конструктор do do no TObject. Вы не только потеряли свой компаньон, но и ваш экземпляр не выполнил остальные необходимые шаги в построении.

Если вы замените его на

inherited Create;

вместо этого компилятор выполняет нормальное разрешение метода. Он просматривает список предков класса и называет первый метод, который он может. В этом случае это:

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

Следовательно, ваш экземпляр правильно создан.

Документация находится здесь: http://docwiki.embarcadero.com/RADStudio/en/Methods#Inherited

Ключевые выдержки:

Если для унаследованного следует имя члена, он представляет собой обычный вызов метода

и

Когда унаследованный не имеет идентификатора после него, он относится к унаследованному метод с тем же именем, что и прилагаемый метод, или, если охватывающий метод является обработчиком сообщений, унаследованному обработчику сообщений для такой же сообщение. В этом случае унаследованный не принимает явных параметров, но передает унаследованному методу те же параметры, с которыми вызывающий метод. Например:

inherited;

часто встречается при реализации конструкторов. Он называет унаследованный конструктор с теми же параметрами, которые были переданы в потомок.

Это довольно странно, не так ли. На первый взгляд кажется удивительным, что называются разные методы. Ключевым моментом является то, что обычный inherited приводит к точному сопоставлению списков параметров. И ваш метод не имеет параметров.

С другой стороны, inherited Create является стандартным вызовом метода. В этом последнем случае вы вызываете метод с одним параметром, используя значение по умолчанию для этого параметра. Поэтому, хотя похоже, что вы вызываете конструктор без параметров, вы этого не делаете. Вы передаете один параметр, ACapacity и значение 0.

Ответ 2

Компаратор - это объект, который необходимо создать самостоятельно. Если бы у вас не было конструктора в вашем спускаемом классе, я бы ожидал, что конструктор по умолчанию будет создан, потому что вы будете неявным образом называть унаследованный конструктор. Если вы создаете свой собственный конструктор, вы всегда должны называть унаследованный Create (по-моему), чтобы позволить предку выполнять свою работу - в этом случае создавая компаратор по умолчанию.