Форум: "Основная";
Текущий архив: 2003.10.16;
Скачать: [xml.tar.bz2];
Вниз
Класс как параметр и перегрузка конструктора Найти похожие ветки
← →
kosm (2003-10-06 11:13) [0]Уважаемые мастера! Растолкуйте плиз, не совсем понимаю что происходит.
Ситуация в следующем. Есть форма с переопределенными и перегруженными конструкторами...
--
TChildForm = class(TForm)
public
constructor Create(AOwner: TComponent); overload; override;
constructor Create(AOwner: TComponent; AParent: TWinControl); reintroduce; overload;
end;
--
Хочу иметь общую ф-цию, для создания экземпляров форм по имени класса (типа CreateForm(TChildForm, fsModal), или что-то типа того).
Проблема в следующем. Если я просто пытаюсь создать форму, то оба конструктора работают на ура...
--
F := TChildForm.Create(Application);
F := TChildForm.Create(Application, Owner);
оба работают.
Если я пытаюсь создать из ф-ции ( CreateForm(TChildForm, fmChild) ), то компилятор ругается на второй конструктор (перегруженный). Почему?
--
type
TFormClass = class of TChildForm;
TFormMode = (fmModal, fmFloat, fmChild);
function CreateForm(AForm: TFormClass; AMode: TFormMode): TForm;
var F: TForm;
begin
case AMode of
fmModal: begin
F := AForm.Create(Application);
F.ShowModal;
end;
fmFloat: begin
F.Show;
F := AForm.Create(Application);
end;
fmChild: begin
F := AForm.Create(Application, Owner);
F.Show;
end;
end;
result := F;
end;
--
СПАСИБО!
← →
Murad (2003-10-06 11:31) [1]Насколько я понимаю дело в том, что второй конструктор не виртуальный.... Но я могу и ошибаться
Class-reference types are useful when you want to invoke a class method or virtual constructor on a class or object whose actual type is unknown at compile time.
← →
Юрий Федоров (2003-10-06 11:40) [2]Возможен конфликт имен
TFormClass уже есть в Forms.pas :
TFormClass = class of TForm;
← →
han_malign (2003-10-06 11:41) [3]>дело в том, что второй конструктор не виртуальный
- абсолютно верно, reintroduce - не подразумевает virtual, нужно явно добавить...
← →
kosm (2003-10-06 12:22) [4]Т.е. Class-reference работает только с виртуальными конструкторами, а reintroduce таковым его не делает?
Понятно. Попробовал конструктор переопределить так:
--
constructor Create(AOwner: TComponent; AParent: TWinControl); reintroduce; overload; virtual;
--
Не помогло - "Too many actual parameters", как будто просто не видит второго конструктора :(
← →
kosm (2003-10-06 12:24) [5]2Юрий Федоров
Спасибо, не углядел :) Но это не из-за него... :(
← →
Юрий Федоров (2003-10-06 12:27) [6]Насчет виртуальности второго конструктора - это вряд-ли приведет к ошибке времени компиляции, скорее ты просто создашь экземпляр не потомка TChildForm, а сам TChildForm.
Если у TChildForm нет потомков, виртуальный конструктор не нужен.
>>Но это не из-за него...
Очень странно...
← →
han_malign (2003-10-06 12:32) [7]а - reintroduce; virtual; overload; ???
- многое от порядка деклараций зависит, да и нужен ли reintroduce - он вообще только от Warning-а помогает...
← →
kosm (2003-10-06 12:42) [8]2Юрий Федоров
То, что не из-за Class-reference, эт точно, тк я у себя его объявление закоментировал...
--
TFormClass = class of TForm;
--
А вот на счет создания экземпляров, это точно, я создаю экземпляр самого TChildForm --> CreateForm(TChildForm, fmChild)
Но разве это как-то может играть роль?
← →
Murad (2003-10-06 12:44) [9]2kosm
>компилятор ругается на второй конструктор (перегруженный).
А как у тебя ругался компилятор в 1-м случае (без virtual)?
← →
kosm (2003-10-06 12:44) [10]2han_malign
reintroduce; virtual; overload; - ругается "Overloaded procedure "Create" must be marked with the "overload" directive"
reintroduce; overload; virtual; - прокатывает, но так же конструктора не видит :(
← →
kosm (2003-10-06 12:46) [11]2Murad
Добавление virtual никак не отразилось :(
По прежнему ругается - "Too many actual parameters"
← →
Murad (2003-10-06 12:48) [12]2kosm
А чего ты вообще паришся, назови второй конструктор по
другому... Чем тебе это не подходит?
← →
kosm (2003-10-06 12:50) [13]По идее можно. Если не найдется причина, то так и сделаю. Просто интересно, в чем трабл-то?
← →
Murad (2003-10-06 12:56) [14]Мне кажется, тогда у тебя где-то конфликт имен кроме TFormClass ... проверь...
← →
Murad (2003-10-06 12:57) [15]Еще Один конфликт налицо ... CreateForm !!!
← →
kosm (2003-10-06 13:06) [16]2Murad
Поправил - MyCreateForm - все тоже самое :(
← →
kosm (2003-10-06 13:20) [17]Похоже дело в том, что ф-ция которая создает форму сидит в другом модуле. Сейчас попробовал второй конструктор по другому назвать, так ф-ция не видит его, грит нет такого конструктора :(
PS: Модуль формы в uses модуля с ф-цией вставил.
← →
Юрий Федоров (2003-10-06 13:32) [18]То, что не из-за Class-reference, эт точно, тк я у себя его объявление закоментировал...
--
TFormClass = class of TForm;
--
А я только что у себя в формс.пас первой строкой написал "йцукенг".
Компилируется без проблем :-)
Понимаешь о чем речь ?
← →
kosm (2003-10-06 13:37) [19]2Юрий Федоров
Если честно - то нет :(
По идее компилятор должен был ругнуться на твой "йцукенг" :)
← →
Юрий Федоров (2003-10-06 13:43) [20]kosm (06.10.03 13:37) [19]
модуль Forms.pas не компилируется при сборке твоего проекта, используется уже заранее подготовленный Forms.dcu
так что править его в данном случае бессмымленно
← →
Murad (2003-10-06 13:45) [21]Самое забавное, что я твой пример выкопировал и у меня компилится и с виртуал и без...
← →
Murad (2003-10-06 13:46) [22]Скорее всего проблема в том, о чем говорит Юра...
← →
kosm (2003-10-06 13:50) [23]2Юрий Федоров
Аааа, ты об этом :) Но у меня как раз ошибка при компиляции этого модуля, где я объявлял TFormClass = class of TForm;
Не, это не из-за него, абсолютно точно (строчку полностью dcuшки все прибил).
Тут вообще какая-то ерунда получается. Сейчас дай думаю назову второй конструктор по другому, черт с ним... Назвал. И теперь ф-ция просто не видит этого конструктора! :( Чего за ерунда?
Просто раньше никогда не работал с сылками на классы, а тут похоже какая-то хитрость есть...
← →
Юрий Федоров (2003-10-06 13:55) [24]Напиши так:
type
T ChildFormClass = class of T ChildForm;
...
function CreateForm(AFormClass: T ChildFormClass; AMode: TFormMode): TForm;
..
или я уже ничего не понимаю в этой жизни...
← →
Murad (2003-10-06 13:56) [25]2kosm
>теперь ф-ция просто не видит этого конструктора!
Это косвенно доказывает, что у тебя там ссылка на VCL-ский
TFormClass... Ты кстати в функции тип параметра изменил, на
TFormClassMY ?
← →
kosm (2003-10-06 13:58) [26]2Murad
Тогда вообще ничего не понимаю... :((((
Почему у меня-то не пашет?
Еще раз кину свой код:
-- childfrm.pas --
uses myfunc;
type
TChildForm = class(TSimpleForm)
public
constructor Create(AOwner: TComponent); overload; override;
constructor CreateChild(AOwner: TComponent; AParent: TWinControl); reintroduce; overload; virtual;
end;
-- myfunc.pas --
type
TMyFormMode = (fmModal, fmFloat);
function MyCreateForm(AForm: TFormClass; AParent: TWinControl = nil; AMode: TMyFormMode = fmModal): TForm;
var F: TForm;
begin
result := nil;
try
if assigned(AParent)
then F := AForm.CreateChild(Application, AParent) <- Здесь говоит что нет такого конструктора
else F := AForm.Create(Application);
case AMode of
fmModal: begin
F.ShowModal;
end;
fmFloat: begin
F.Show;
end;
end;
result := F;
except
on E: Exception do;
end; // try/except
end;
------------------------------------------
← →
Skier (2003-10-06 13:59) [27]Ты вообще читаешь что тебе пишут или ждёшь готовый код ?
var F: TChildForm;
← →
Murad (2003-10-06 14:01) [28]2kosm
> function MyCreateForm(AForm: ; AParent:
TWinControl = nil; AMode: TMyFormMode = fmModal): TForm;
Ну ты и маньяк!!! :)))
Тебе же говорят ....
Назови тип не TFormClass а TFormClassMY
← →
Murad (2003-10-06 14:02) [29]2kosm
> function MyCreateForm(AForm: TFormClassMY; AParent:
TWinControl = nil; AMode: TMyFormMode = fmModal): TForm;
← →
kosm (2003-10-06 14:03) [30]Ребята, все, спасибо! Действительно дело было в
type
TChildFormClass = class of TChildForm;
Чучело, одним словом :) Теперь все понял!
ОГРОМНОЕ СПАСИБО!
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.10.16;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.01 c