Delphi/pascal: перегрузка конструктора другим прототипом
Я пытаюсь создать дочерний класс TForm с
- специальный конструктор для определенных случаев и
- конструктор по умолчанию, который будет поддерживать совместимость с текущим кодом.
Это код, который у меня есть сейчас:
interface
TfrmEndoscopistSearch = class(TForm)
public
/// original constructor kept for compatibility
constructor Create(AOwner : TComponent); overload; override;
/// additional constructor allows for a caller-defined base data set
constructor Create(AOwner : TComponent; ADataSet : TDataSet; ACaption : string = ''); overload;
end;
Кажется, что работает, но я всегда получаю предупреждение от компилятора:
[Warning] test.pas(44): Method 'Create' hides virtual method of base type 'TCustomForm'
- Добавление "перегрузки"; после того, как второй конструктор не будет компилироваться. "[Ошибка] test.pas(44): Декларация" Создать "отличается от предыдущей декларации".
- делает второй конструктор функцией класса компилируется без каких-либо ошибок или предупреждений, но умирает с нарушением доступа во время выполнения (все члены vars равны нулю).
Ответы
Ответ 1
Попробуйте добавить reintroduce
до второго overload
, например:
TfrmEndoscopistSearch = class(TForm)
public
/// original constructor kept for compatibility
constructor Create(AOwner : TComponent); overload; override;
/// additional constructor allows for a caller-defined base data set
constructor Create(AOwner : TComponent; ADataSet : TDataSet; ACaption : string = ''); reintroduce; overload;
end;
Это компилируется в Turbo Delphi. Мне понадобился public
, чтобы он скомпилировался, потому что перегрузка методов published
ограничена.
Ответ 2
Там действительно простой способ избежать этого. Дайте вашему новому конструктору другое имя.. В отличие от некоторых других популярных языков, Delphi назвал конструкторы; вам не нужно называть их Create. Вы можете назвать свой новый CreateWithDataset и вообще не вмешиваться в виртуальный конструктор Create.
TfrmEndoscopistSearch = class(TForm)
/// original constructor kept for compatibility
constructor Create(AOwner: TComponent); override;
/// additional constructor allows for a caller-defined base data set
constructor CreateWithDataset(AOwner: TComponent; ADataSet: TDataSet; ACaption: string = '');
end;
Фактически, если вы не создаете экземпляр этого класса полиморфно, вам даже не нужен оригинальный конструктор. Вы можете объявить свой новый следующим образом:
TfrmEndoscopistSearch = class(TForm)
/// additional constructor allows for a caller-defined base data set
constructor Create(AOwner: TComponent; ADataSet: TDataSet; ACaption: string = ''); reintroduce;
end;
Попытка вызвать конструктор с одним аргументом непосредственно на TfrmEndoscopistSearch приведет к ошибке компиляции.
(Создание его полиморфно обычно связано с использованием Application.CreateForm:
Application.CreateForm(TfrmEndoscopistSearch, frmEndoscopistSearch);
Это всегда вызывает виртуальный конструктор с одним аргументом, введенный в TComponent. Если это не ваша основная форма, вам не нужно это делать. Я уже писал о моих ощущениях на Application.CreateForm.
Ответ 3
constructor Create(AOwner:Tcomponent;str:string);overload;
...
constructor TfrmEndoscopistSearch.Create(AOwner: Tcomponent; str: string);
begin
inherited Create(AOwner);
showmessage(str);
end;
Это должно сделать трюк