Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Еще раз про class of [D6, Win95/98]


Igorek ©   (2002-08-02 13:02:00) 

Вот такой код.
unit Unit2;

interface
type
TA = class
end;
TB = class (TA)
end;
TC = class (TA)
end;
TTA = class of TA;
var
vb: TB;
vc: TC;
refta: TTA;
implementation

procedure P2;
begin
refta := TB;
end;

procedure P1;
begin
P2;
//ниже что-то типа vb := refta.Create
//или
// if refta.InheritsFrom(vb.ClassType) then
// vb := vb.ClassType(refta.Create)

if refta.InheritsFrom(vb.ClassType) then
vb := TB(refta.Create)
else
if refta.InheritsFrom(TC) then
vc := TC(refta.Create)
else
//error
;
end;

end.

Как в теле процедуры P1 избежать прямого использования названий типов TB и TC?

Если такой вопрос уже был, то можете просто сказать об этом - я поищу.


vuk   (2002-08-02 16:11:00) [1]

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


DiamondShark   (2002-08-02 16:03:00) [2]


> Ну какие закидоны, уважаемый? Предельно точно сформулированная
> проблема.


Закидоны в том, что вы становитесь в позу типа "не въехал -- значит не твоего ума дело"

Точная формулировка возможна только на человеческом языке, потому как проблема стоит перед человеком -- перед вами в данном случае. А о проблеме то мы ничего и не знаем, видим только результат попытки решения, и результат тупиковый, раз уж вы здесь.

А приведение фрагмента ошибочного и бессмысленного кода не есть точная формулировка, ибо в таком случае указание пальцем на место ошибки можно назвать предельно точным решением.


> И все равно не вижу ошибки - и компилится и выполняется.
> Даже мастера ничего не заметили.


Вот такой код

var
P: PInteger;
begin
P^ := 1234;
end;

Несомненно будет компилироваться, и временами даже исполняться.

Экземпляр для vbнигде не создается. А между тем, ClassType обычный метод, не классовый, и работает он, между прочим, с указателем Self, который вы не потрудились инициализировать.


vuk   (2002-08-02 15:55:00) [3]

TObject(vb) := refta.Create


Igorek   (2002-08-02 15:52:00) [4]

2 DiamondShark © (02.08.02 15:44)

> Ну вы, товарищ, совсем...
>
> Таких проблем я могу четко наформулировать мульен.

Так формулируйте себе, на здоровье. Не нравиться данная формулировка - игнорируйте.

Чем же я именно Вас так задел? Вроде никто больше не возмущается.


MBo   (2002-08-02 15:47:00) [5]

>Дело в том, что это проблема не конкретная, а пример более общего случая. Так что условие не меняется.
Как бы то ни было, придется использовать общего предка, но не наоборот

пример, создающий контрол введенного в edit1 имени класса, если такие уже имеются на форме (иначе RegisterClass понадобится)
используется общий предок TWinControl

function TForm1.FindSuch(Root:TComponent;const s: String): TComponent;
var i:integer;
begin
Result:=nil;
for i:=0 to root.componentcount-1 do begin
if sametext(root.Components[i].classname,s) then begin
Result:=Root.Components[i];
Break;
end;
end;
end;

procedure TForm1.Button6Click(Sender: TObject);
type
TWCClass = class of TWinControl;
var
Obj:TWinControl;
ObjClass:TWCClass;
s:string;
c:tcomponent;
begin
s:=edit1.text;
c:=FindSuch(TComponent(self),s);
if c<> nil then begin
ObjClass:=TWCClass(c.classtype);
if ObjClass<>nil then begin
Obj:=ObjClass.Create(self);
Obj.Parent:=self;
Obj.SetBounds(10,10,100,20);
end;
end;
end;


DiamondShark   (2002-08-02 15:44:00) [6]


> А какая разница? Есть четко сформулированная проблема


Ну вы, товарищ, совсем...

Таких проблем я могу четко наформулировать мульен.

Вот предложу вам нечто склепанное из пустых бочек, грубо отесаных досок и ящиков для стеклотары, а потом предложу вам объянить мне, почему это не летает. А на справедливый вопрос "это что за хрень такая" встану в позу и заявлю что "я все сказал"


Igorek   (2002-08-02 15:35:00) [7]

2 DiamondShark © (02.08.02 15:27)

> А закидоны Вы бросьте. Хотите ответа, так выражайтесь так
> чтоб Вас поняли.

Ну какие закидоны, уважаемый? Предельно точносформулированная проблема.

И все равно не вижу ошибки - и компилится и выполняется. Даже мастера ничего не заметили.

2 MBo © (02.08.02 15:26)

> так объяви vb как TA

Дело в том, что это проблема не конкретная, а пример более общего случая. Так что условие не меняется.


DiamondShark   (2002-08-02 15:27:00) [8]


if refta.InheritsFrom(vb.ClassType) then
^Здесь ошибка
vb := TB(refta.Create)
else
if refta.InheritsFrom(TC) then
vc := TC(refta.Create)
else
//error


А закидоны Вы бросьте. Хотите ответа, так выражайтесь так чтоб Вас поняли.


MBo   (2002-08-02 15:26:00) [9]

>Но компилятор не пропустит - Incompatible types TA and TB.
так объяви vb как TA


Igorek   (2002-08-02 15:21:00) [10]

2 Старый Паскалист (02.08.02 15:07)

> В чём состоит идея?

А какая разница? Есть четко сформулированная проблема.

> И вообще, динамическое создание экземпляра неизвестного
> типа имеет смысл только при наличии виртуального конструктора.

Естесно. Просто я его для простоты не написал.


Старый Паскалист   (2002-08-02 15:07:00) [11]

Igorek © Ты не сказал самого главного - зачем тебе это нужно.
В чём состоит идея?

И вообще, динамическое создание экземпляра неизвестного типа имеет смысл только при наличии виртуального конструктора.
(За исключением вырожденных случаев).


Igorek   (2002-08-02 15:04:00) [12]

2 Юрий Зотов © (02.08.02 14:28)

> Просто раскомментируйте эту строку и закомментируйте последующие.
> Получим:
>
> procedure P1;
> begin
> P2;
> vb := refta.Create //Создаст экземпляр класса, который назначен
> в P2

Спасибо за ответ.
Но компилятор не пропустит - Incompatible types TA and TB.
В этом и вся проблема.

2 DiamondShark © (02.08.02 13:22)
Ошибок в коде нет и сказал я достаточно.


Юрий Зотов   (2002-08-02 14:28:00) [13]

> //ниже что-то типа vb := refta.Create

Просто раскомментируйте эту строку и закомментируйте последующие.
Получим:

procedure P1;
begin
P2;
vb := refta.Create //Создаст экземпляр класса, который назначен в P2
end;


DiamondShark   (2002-08-02 13:22:00) [14]

А по-русски слабо рассказать, что нужно?

Приведенный код мало, что бессмысленный, так еще и с ошибками.


Наверх

Титульная страница Поиск, карта сайта Написать письмо