Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.06.29;
Скачать: CL | DM;

Вниз

Создание объекта от переменной класса   Найти похожие ветки 

 
PONTIY   (2005-06-06 16:27) [0]

У нас имеется переменная какого-то определенного класса
(допустим: var Variable: TVariable), но в нужном фрагменте кода класс этой переменной нам неизвестен. Вопрос: как создать (create) объект имея только лишь эту переменную?


 
Digitman ©   (2005-06-06 16:28) [1]

никак


 
Skier ©   (2005-06-06 16:31) [2]

Можно через TObject.ClassType извернуться, но кастить придётся...


 
VladimirB ©   (2005-06-06 16:39) [3]

new_var:=Variable.Create;


 
Digitman ©   (2005-06-06 16:40) [4]


> в нужном фрагменте кода класс этой переменной нам неизвестен


если этот фрагмент успешно скомпилирован, значит известен.


 
Anatoly Podgoretsky ©   (2005-06-06 16:44) [5]

Skier ©   (06.06.05 16:31) [2]
Для этого придется сначала в этой переменной создать объект, только потом можно будет воспользоваться этим.


 
Skier ©   (2005-06-06 16:46) [6]

>Anatoly Podgoretsky ©   (06.06.05 16:44) [5]
Угу.


 
HeathRow   (2005-06-07 10:05) [7]

Уточню ситуацию. Переменная Variable в зависимости от условий ранее идущего кода можеть иметь разные классы: TVariable/TVariable1/TVariable2...
И вся задача состоит в том что бы при .. := <ClassName>.Create(..) указать соответствующий переменной класс.

Как вариант можно сделать так:

if (Variable is TVariable1) then Variable := TVariable1.Create(..);
if (Variable is TVariable2) then Variable := TVariable2.Create(..);
и т.д.

Но если классов этой переменной будет много, то перечислять их все в if-ах мягко говоря будет неудобно.


 
jack128 ©   (2005-06-07 10:17) [8]

HeathRow   (07.06.05 10:05) [7]
(Variable is TVariable1)

Оператор is доступен только если объект уже создан, тогда происходит вызов InheritsFrom либо если переменная = nil , тогда is всегда вернет False.

соответственно либо у тебя в коде мемлик(если выше по коду Variable уже создана), либо не одно условие не выполнится..


 
Alexander Panov ©   (2005-06-07 10:20) [9]

HeathRow   (07.06.05 10:05) [7]
...от условий ранее идущего кода можеть иметь разные классы...


Это как?

Можно пример привести?


 
panov ©   (2005-06-07 10:21) [10]

>HeathRow   (07.06.05 10:05) [7]
Не надо разные ники использовать.


 
TUser ©   (2005-06-07 10:23) [11]

Еще можно написать
TVarClass = class of TVariable;

и потом для любого наследника
var V: TVarClass;
begin
 V:={тем или иным способом находим нужный класс}
 Variable:=V.Create;
end;


 
jack128 ©   (2005-06-07 10:25) [12]

TUser ©   (07.06.05 10:23) [11]
желательно, чтобы конструктор у TVariable был виртуальный..


 
PVOzerski ©   (2005-06-07 10:36) [13]

На самом деле компилятор - штука более мудреная, чем это кажется на 1-й взгляд. Сейчас он меня удивил. Я написал такой код:

var
 Control: TWinControl;
procedure TForm1.Button1Click(Sender: TObject);
begin
 Control := nil;
 ShowMessage(inttostr(integer(Control is TWinControl)));
end;

И прогнал его под D3, D6 и D7. Применительно к D6 и D7 прав jack128 (да и я такое же ожидал). А вот в D3 is работает как-то иначе: если переменной не присвоен объект какого-то класса, is отрабатывает согласно описанию переменной. Притом на ClassType или ClassName это не распространяется: AV однозначно. В любом случае, фича не документирована и рекомендоваться к использованию не может.

Применительно к сабжу: рекомендую завести переменную типа class of TVariable и "в зависимости от условий ранее идущего кода" присваивать ей "TVariable/TVariable1/TVariable2...". И далее ей и пользоваться при вызове конструктора.


 
PONTIY   (2005-06-07 10:44) [14]

to jack128 спасибо, учту
to panov извиняюсь, пишу с разных компьютеров, неуследил


> Alexander Panov ©   (07.06.05 10:20) [9]
> HeathRow   (07.06.05 10:05) [7]
> ...от условий ранее идущего кода можеть иметь разные классы...
>
> Это как?
>
> Можно пример привести?


изначально
var Variable: TObject;
...
далее в коде происходит такое присваивание

Variable := Var1 // где Var1: TVariable1
или
Variable := Var2 // где Var2: TVariable2
и т.д.

to TUser


> V:={тем или иным способом находим нужный класс}

Можно о том что внутри {} поподробней?


 
TUser ©   (2005-06-07 10:47) [15]

> Можно о том что внутри {} поподробней?

У тебя класс создаваемого объекта определяется в ранее выполняемом коде:
> Переменная Variable в зависимости от условий ранее идущего
> кода можеть иметь разные классы: TVariable/TVariable1/TVariable2...


Вот в этом ранее идущем коде и пропиши алгоритм определения будущего класса.


 
Alexander Panov ©   (2005-06-07 10:53) [16]

HeathRow   (07.06.05 10:05) [7]
Переменная Variable в зависимости от условий ранее идущего кода можеть иметь разные классы: TVariable/TVariable1/TVariable2...


Не может переменная определенного класса быть переменной другого класса.

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

Говорить можно об объектах разных классов.

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


 
Bel ©   (2005-06-07 10:55) [17]

> Variable := Var1 // где Var1: TVariable1
> или
> Variable := Var2 // где Var2: TVariable2
> и т.д.

Ну и зачем создавать экземпляр объекта, если ему уже присваивается указатель на другой объект?


 
Bel ©   (2005-06-07 10:58) [18]

>... если ему уже присваивается указатель на другой объект?

если переменной уже присваивается указатель на другой объект?
Сорри, очепятка.


 
PVOzerski ©   (2005-06-07 11:01) [19]

Вот маленькая иллюстрация того, как бы я решал такую задачу. На красоту и последовательность применения ООП не претендую :)

type
 TVariable = class
 end;

 TVariable1 = class(TVariable);
 TVariable2 = class(TVariable);

 TVariableClass = class of TVariable;

var
 MyVarClass: TVariableClass = TVariable;
 MyVar: TVariable;

function VarCreate: TVariable;
begin
 Result := MyVarClass.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 MyVarClass := TVariable1;
 MyVar := VarCreate;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 MyVarClass := TVariable2;
 MyVar := VarCreate;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 if Assigned(MyVar) then
   begin
     TClass(MyVarClass) := MyVar.ClassType;
     MyVar.Free;
     MyVar := VarCreate;
   end;
end;


 
icWasya ©   (2005-06-07 11:10) [20]

>PVOzerski ©   (07.06.05 11:01) [19]
небольшое добавление - без него не будет работать
type
TVariable = class
  constructor Create;Virtual;
end;


constructor TVariable.Create;
begin
end;


 
PVOzerski ©   (2005-06-07 11:19) [21]

Точнее, работать-то будет, но вот если конструкторы у TVariable, TVariable1 и TVariable2 разные, то их надо делать виртуальными.


 
Abessalom   (2005-06-07 16:14) [22]


> var
>  Control: TWinControl;
> procedure TForm1.Button1Click(Sender: TObject);
> begin
>  Control := nil;
>  ShowMessage(inttostr(integer(Control is TWinControl)));
> end;


Control := nil;
if Control is TWinControl then..

Компилируется вот так:
...
cmp dword ptr [Control], $00
jz +$1d
...
Улавливаете?


 
iskatel ©   (2005-06-08 03:09) [23]

почему бы их не создавать уже при присваивании?



Страницы: 1 вся ветка

Текущий архив: 2005.06.29;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.028 c
9-1111583096
StrangeMan
2005-03-23 16:04
2005.06.29
Игровые конструкторы


6-1112392985
Muh
2005-04-02 02:03
2005.06.29
Почему у флешгета получается, а у меня нет :)


10-1094535960
Cobalt
2004-09-07 09:46
2005.06.29
Помогите найти ошибку в коде


1-1118096582
Gopher
2005-06-07 02:23
2005.06.29
команда GetWindowsDir


4-1115175884
Alexandr_jr
2005-05-04 07:04
2005.06.29
CreateFileMapping&amp;MapViewOfFile