Casa
Top.Mail.Ru Yandeks.Metrika
Fórum: "Principal";
Arquivo atual: 2004.02.02;
Download: [xml.tar.bz2];

Para baixo

Crie uma variável da classe atual. Encontre agências semelhantes


tria   (2004-01-21 14:29) [0]

Вопрос в следующем. Есть иерархия:
TBaseClass=Class;
TClass1=Class(TBaseClass);
TClass2=Class(TBaseClass1);
TClass11=Class(TBaseClass);

Есть процедура, в кот. передается переменная класса:
procedure Proc1(p:TBaseClass);
var p1:TBaseClass;
começar
p1:=TBaseClass.Create;
... и чего то там еще...
end;

Переменная p может быть любого из вышеприведенных типов (TClass1,TClass2,TClass11).
Задача: создать p1 того же типа, что и фактически переданный параметр.



Skier   (2004-01-21 14:32) [1]

метакласс используй.



Тимохов   (2004-01-21 14:33) [2]

p.ClassType.Create;



tria   (2004-01-21 14:34) [3]

Честно говоря, не знаю что это такое.



Тимохов   (2004-01-21 14:34) [4]

Правда, еще зависит от того как у тебя выглядит Create.



tria   (2004-01-21 14:36) [5]

Спасибо, Тимохов.



Тимохов   (2004-01-21 14:36) [6]


> Честно говоря, не знаю что это такое.

Если ты про [2], то воспользуйся F1.



Тимохов   (2004-01-21 14:48) [7]

Para o autor
Обрати внимание на Тимохов © (21.01.04 14:34) [4].
Если ты собираешься делать в каждом классе свой конструктор Create, то делай в базовом классе его virtual, а в потомках override.

И вообще я немного не прав:
писать надо так TBaseClasses(p.ClassType).Create, где TBaseClasses = class of TBaseClass. Иначе будет вызваться Create у TObject, а твой create вообще не будет вызываться.



pasha_golub   (2004-01-21 15:02) [8]

2Тимохов
В принципе про это Skier и говорил.



Тимохов   (2004-01-21 15:04) [9]

pasha_golub © (21.01.04/15/02 8:XNUMX) [XNUMX]
Просто у скаера были очень умные слова, которые не всем понятны (даже мне :))))
Полагаю, что он это и имел в виду.



pasha_golub   (2004-01-21 15:21) [10]

2Тимохов © (21.01.04 15:04) [9]
Эт точно. :-) На то он и Мастер.



Юрий Зотов   (2004-01-21 16:29) [11]

> tria © (21.01.04 14:29)

А если без умных слов, и поконкретнее, то так.

tipo
TBaseClass = classe
...
constructor Create(...); virual;
...
end;

TClassOfBaseClass = class of TBaseClass;

TClass1 = class(TBaseClass)
...
end;

TClass2 = class(TBaseClass1)
...
end;

и т.д.

procedure Proc1( RealBaseClass: TClassOfBaseClass);
var
p1: TBaseClass;
começar
p1 := RealBaseClass.Create(...);
...
end;



Тимохов   (2004-01-21 16:34) [12]

Yuri Zotov © (21.01.04 16: 29) [11]

1. Ему надо не procedure Proc1(RealBaseClass: TClassOfBaseClass), а procedure Proc1(RealBaseClass: TBaseClass), что согласитель разные вещи.
2. Про конструктор он вообще ничего не сказал - может ему штатного TOBject.Create хватит, тогда не надо virtual



Юрий Зотов   (2004-01-21 16:45) [13]

> Timokhov © (21.01.04 16: 34) [12]

> что согласитель разные вещи.

Разные. Но ClassType еще не отменили. И я полагаю, что решение задачи о поимке ручного льва в пустыне Сахара должно нами рассматриваться так же, как и в той книжке, где эта задача была впервые сформулирована.

> 2. Про конструктор он вообще ничего не сказал - может ему
> штатного TOBject.Create хватит, тогда не надо virtual

А вот здесь Вы, IMVHO, очень сильно и очень принципиально ошибаетесь. При статическом конструкторе будет всегда создаваться объект одного и того же класса - того, который объявлен в самой процедуре. TBaseClass, в общем.



Тимохов   (2004-01-21 17:03) [14]


> А вот здесь Вы, IMVHO, очень сильно и очень принципиально
> ошибаетесь. При статическом конструкторе будет всегда создаваться
> объект одного и того же класса - того, который объявлен
> в самой процедуре. TBaseClass, в общем.


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

tipo
tcc1 = class of tc1;
tc1 = class(tobject)
procedure show; virtual;
end;
tc2 = class(tc1)
procedure show; override;
end;

procedure tc1.show;
começar
showmessage("



Тимохов   (2004-01-21 17:05) [15]


> > Тимохов © (21.01.04 16:34) [12]
>
> > что согласитель разные вещи.
>
> Разные. Но ClassType еще не отменили. И я полагаю, что решение
> задачи о поимке ручного льва в пустыне Сахара должно нами
> рассматриваться так же, как и в той книжке, где эта задача
> была впервые сформулирована.


С этим тоже сложно согласиться. Задача в том, что есть объект надо сделать его клон того же класса.

Все правы, но автор спрашивал другое.



Тимохов   (2004-01-21 17:21) [16]

Юрий Зотов!
Откликнитесь на [14]. Может я что-то не так понимаю? Мне чессослово интересно...



Юрий Зотов   (2004-01-21 17:29) [17]

> Timokhov © (21.01.04 17: 21) [16]

А чего тут не понимать? Зависит от реализации. Если использовать метакласс - то да, а если нет - то при статическом конструкторе всегда будет создаваться один и тот же класс.



Тимохов   (2004-01-21 17:38) [18]

Что-то не очень понятно.

В 14 был приведен пример, который вроде как противоречит вашему возражению из 13 на мою фразу "Про конструктор он вообще ничего не сказал - может ему штатного TOBject.Create хватит, тогда не надо virtual". Вы сказали, что я принципиально ошибаюсь, может все-таки не принципиально и не ошибаюсь вовсе? :)))

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

Да вобщем-то и в Вашем примере из 11 не обязательно делать virtual - будет работать правильно и без этого.



Skier   (2004-01-21 17:40) [19]

> Timokhov © (21.01.04 17: 38) [18]
А ты проверь без virtual ...через ClassName...



Тимохов   (2004-01-21 17:44) [20]

Esquiador © (21.01.04 17: 40) [19]
Все работает

Я прорюхал про что речь и в чем наше непонимание.
Если в каждом классе потомке BaseClass нужен свой конструктор, то нужно писать в TBaseClass.crate; virtual; Если же все потомки могут обойтить конструктором TBaseClass.crate, то virtual не нужен.



Тимохов   (2004-01-21 17:45) [21]

Т.о. все зависит от исходной задачи...



Skier   (2004-01-21 17:48) [22]


> Т.о. все зависит от исходной задачи...

всё зависит от того что попадёт в ссылку на класс.



Тимохов   (2004-01-21 17:49) [23]


> всё зависит от того что попадёт в ссылку на класс.

Замечание не понято :(((



Skier   (2004-01-21 17:50) [24]


> Замечание не понято :(((

Uma pena ...



Тимохов   (2004-01-21 17:52) [25]

Esquiador © (21.01.04 17: 50) [24]
Это уже наезд... :(((
Во всем, что я сказал я, к сожалению для некоторых, прав.



tria   (2004-01-21 18:18) [26]

> Esquiador
А можно замечание повторить поподробней? А то мне с этим жить, и уж больно хочется разобраться?



tria   (2004-01-21 18:24) [27]

Пример, который привел Тимохов работает, ClassName возвращает tc2. Подводных камней, к сожалению, не вижу.
Конструктор у меня пока один на все классы, но в дальнейшем может и будут разные. Проверил - вызывается конструктор нужного класса.



Тимохов   (2004-01-21 18:26) [28]

tria © (21.01.04 18:24) [27]
Если у тебя может быть потребность в разных конструкторах (т.е. в потомке нужен свой конструктор) то слушайся Юрия Зотовова. Приши в TBaseClass constructor Create; virtual и создавай объекты так TBaseClasses(p.ClassType).Create.



tria   (2004-01-21 18:30) [29]

Timokhov
Eu entendi.
Проверил - это взял Ваш код, добавил конструктор с директивой virtual, перекрыл в наследнике. При создании вызвался конструктор класса tc2. Так что на мой взгляд Ваш код рабочий.



Тимохов   (2004-01-21 18:38) [30]

Все мысли высказанные тут рабочие - все зависит от Вашей потребности.

С методологической точки зрения самый правый (в смысле правильный) это Юрий Зотов - всегда пишите у конструктора virtual и всегда все будет ОК.



Тимохов   (2004-01-21 18:55) [31]


> Проверил - это взял Ваш код, добавил конструктор с директивой
> virtual, перекрыл в наследнике. При создании вызвался конструктор
> класса tc2. Так что на мой взгляд Ваш код рабочий.

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

В качестве примера можете это посмотреть

tipo
tcc1 = class of tc1;
tc1 = class(tobject)
constructor create();
end;
tc2 = class(tc1)
constructor create();
end;

constructor tc1.create();
começar
showmessage("tc1 constructor, class name = "+classname);
end;

constructor tc2.create();
começar
showmessage("tc2 constructor, class name = "+classname);
end;

procedure p(o: tcc1);
var
oo: tc1;
começar
oo := o.create();
end;

procedimento TForm1.Button10Click (Sender: TObject);
começar
p(tc1); // создается класс Tc1 вызывается констр. tc1.create.
p(tc2); // создается класс Tc2 вызывается констр. tc1.create.
end;

Вообще хочу вернуться к совету слушать Юрия Зотова. Повторюсь, что с точки зрения методики написания программ он более прав.



tria   (2004-01-21 19:07) [32]

Собственно говоря, последний пример - наиболее простое решение задачи ...



Тимохов   (2004-01-21 19:13) [33]


> Собственно говоря, последний пример - наиболее простое решение
> задачи ...

Вы имели в виду пример из [31]?
Все-таки лучеше пишите virtual :))) Спокойнее будет жизнь...



tria   (2004-01-21 19:19) [34]

Ладно уж стебаться...
Подведу для себя итог: всей глубины вопроса я так и не осознал, но как решить мою задачу и к каким последствиям может привести то или иное решение понял.
Всем еще раз спасибо, убегаю на очень приятное занятие - играть в футбол.



Страницы: 1 filial inteira

Fórum: "Principal";
Arquivo atual: 2004.02.02;
Download: [xml.tar.bz2];

em cima





Memória: 0.67 MB
Hora: 0.042 c
6-2256
kolyan
2003-11-24 07:19
2004.02.02
Como descobrir o endereço IP do seu computador?


1-2143
Seryozha
2004-01-21 21:21
2004.02.02
Componente


7-2391
Xhunter
2003-11-14 20:59
2004.02.02
Problemas de serviço


3-1955
WG
2004-01-08 16:57
2004.02.02
Como salvar texto de blob em arquivo?


3-1986
SMU
2004-01-08 15:44
2004.02.02
Como instalar o BDE sem o Delphi?





afrikaans albanês Arabic armênio azerbaijano basco belarusian Bulgarian catalão Chinês simplificado) Chinês tradicional) croata checo dinamarquês Dutch Inglês estoniano filipino Finnish French
Galego georgiano German grego crioulo haitiano hebraico hindi húngaro islandês Indonesian irlandês Italian Japanese Korean letão lituano macedónio Malay maltês Norwegian
persa polonês Portuguese Romeno Russa sérvio Slovak esloveno Espanhol swahili sueco tailandês turco ucraniano urdu vietnamita galês ídiche bengali bósnio
cebuano esperanto gujarati hausa hmong igbo javanês kannada khmer lao latino maori marata mongol Nepali punjabi somali tâmil telugu yoruba
zulu
Английский francês Alemão Italiano Португальский russo Espanhol