主页
Top.Mail.Ru Yandeks.Metrika
论坛:“主要”;
当前存档:2004.02.02;
下载:[xml.tar.bz2];

向下

创建当前类的变量。 找到类似的分支


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;
开始
p1:=TBaseClass.Create;
... и чего то там еще...
结束;

Переменная 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]

作者
Обрати внимание на Тимохов © (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]

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



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

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



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

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



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

> tria © (21.01.04 14:29)

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

类型
TBaseClass = class
...
constructor Create(...); virual;
...
结束;

TClassOfBaseClass = class of TBaseClass;

TClass1 = class(TBaseClass)
...
结束;

TClass2 = class(TBaseClass1)
...
结束;

等等

procedure Proc1( RealBaseClass: TClassOfBaseClass);
VAR
p1: TBaseClass;
开始
p1 := RealBaseClass.Create(...);
...
结束;



Тимохов   (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]

> Тимохов © (21.01.04 16:34) [12]

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

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

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

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



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


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


也许检查?

类型
tcc1 = class of tc1;
tc1 = class(tobject)
procedure show; virtual;
结束;
tc2 = class(tc1)
procedure show; override;
结束;

procedure tc1.show;
开始
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]
А ты проверь без 虚拟 ...через ClassName...



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

滑雪者©(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]


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

可惜......



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

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



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

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



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
我懂了
Проверил - это взял Ваш код, добавил конструктор с директивой virtual, перекрыл в наследнике. При создании вызвался конструктор класса tc2. Так что на мой взгляд Ваш код рабочий.



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

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

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



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


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

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

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

类型
tcc1 = class of tc1;
tc1 = class(tobject)
构造函数create();
结束;
tc2 = class(tc1)
构造函数create();
结束;

constructor tc1.create();
开始
showmessage("tc1 constructor, class name = "+classname);
结束;

constructor tc2.create();
开始
showmessage("tc2 constructor, class name = "+classname);
结束;

procedure p(o: tcc1);
VAR
oo: tc1;
开始
oo := o.create();
结束;

过程TForm1.Button10Click(Sender:TObject);
开始
p(tc1); // создается класс Tc1 вызывается констр. tc1.create.
p(tc2); // создается класс Tc2 вызывается констр. tc1.create.
结束;

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



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

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



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


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

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



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

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



Страницы: 1 整个分支

论坛:“主要”;
当前存档:2004.02.02;
下载:[xml.tar.bz2];

楼上









内存:0.68 MB
时间:0.042 c
3-2023
饰钉
2004-01-06 15:11
2004.02.02
сортировка dbchart


4-2437

2003-11-26 12:33
2004.02.02
图标=文件类型?


3-1950
德米特里
2004-01-05 15:16
2004.02.02
越野车


1-2138
pasha_golub
2004-01-19 14:20
2004.02.02
Delphi 6和CorelDraw 11交互


1-2156
OlegL
2004-01-21 17:03
2004.02.02
组合框





南非荷兰语 阿尔巴尼亚人 阿拉伯语 亚美尼亚 阿塞拜疆 巴斯克 白俄罗斯 保加利亚语 加泰罗尼亚 简体中文 中国(繁体) 克罗地亚 捷克 丹麦语 荷兰人 英语 爱沙尼亚语 菲律宾人 芬兰 法文
加利亚西语 格鲁吉亚语 德语 希腊语 海地克里奥尔语 希伯来语 印地语 匈牙利 北日耳曼语 印度尼西亚人 爱尔兰语 意大利语 日本性玩偶 韩语 拉脱维亚 立陶宛 马其顿 马来语 马耳他语 挪威语
波斯语 波兰语 葡萄牙语 罗马尼亚 俄语 塞尔维亚 斯洛伐克 斯洛文尼亚 西班牙语 斯瓦希里 瑞典语 泰国人 土耳其 乌克兰 乌尔都语 越南人 威尔士语 意第绪语 孟加拉 波斯尼亚
宿务 世界语 古吉拉特语 豪萨语 苗族 伊博 爪哇 卡纳达语 高棉 老挝 拉丁语 毛利 马拉 蒙古人 尼泊尔 旁遮普 索马里 泰米尔人 泰卢固语 约鲁巴语
祖鲁
英文 Французский Немецкий Итальянский Португальский 俄文 Испанский