Форум: "Прочее";
Текущий архив: 2013.06.02;
Скачать: [xml.tar.bz2];
ВнизСоздать определенный класс. Найти похожие ветки
← →
vxxv (2013-01-21 14:44) [0]Допустим есть базовый класс: BaseClass.
От него наследуются Class_1, Class_2... и т.д.
Допустим нужно сейчас создать Class_2.
Как определить, что именно этот класс нужно создавать?
Так:
function CreateClass(Type_: Integer): BaseClass;
begin
case Type_ of
TYPE_CLASS_1: Result:= Class_1.Create;
TYPE_CLASS_2: Result:= Class_2.Create;
...
end;
end;
Или как?
← →
Ega23 © (2013-01-21 14:59) [1]
TSomeClass = class
public
constructor Create; virtual;
end;
TClassOfSomeClass = class of TSomeClass;
TSecondClass = class (TSomeClass);
TThirdClass = class (TSomeClass);
function CreateClass(aClassType: TClassOfSomeClass): TSomeClass;
begin
Result := aClassType.Create;
end;
CreateClass(TSomeClass);
CreateClass(TSecondClass);
CreateClass(TThirdClass);
← →
TUser © (2013-01-21 15:35) [2]Я бы мелкую прожку написал, которая генерит нечто вроде
{ }
{ This file is autogenerated by GenerateCode program }
{ }
function CreateElementByName (const Name: string): TSimpleElement;
begin
if Name = "" then
result := TSimpleElement.Create
else
if Name = "map" then
result := TMapElement.Create
else
if Name = "map_all" then
result := TMapElementLst.Create
else
if Name = "sht" then
result := TSheetElement.Create
else
if Name = "sht_all" then
result := TSheetElementLst.Create
else
if Name = "reg" then
result := TRegion.Create
else
if Name = "reg_all" then
result := TRegionLst.Create
else
if Name = "hel" then
result := THelixElement.Create
else
if Name = "hel_all" then
result := THelixElementLst.Create
else
{%all off}{%proton on printscript on}
if Name = "unit" then
result := TArchUnitElement.Create
else
if Name = "unit_all" then
result := TArchUnitElementLst.Create
else
{%all on}
....
потому что переносимость - FreePascal под Linux это читает и ему хорошо. А как он с RTTI совместим у меня не было желания выяснять. Чем проще, тем универсальнее.
← →
Dimka Maslov © (2013-01-21 21:57) [3]
type
TSomeClass = class
public
constructor Create; virtual;
end;
TClassOfSomeClass = class of TSomeClass;
TSecondClass = class (TSomeClass);
TThirdClass = class (TSomeClass);
const
Classes: array[1..3] of TClassOfSomeClass = (TSomeClass, TSecondClass,
TThirdClass);
function CreateClass(Index: Integer): TSomeClass;
begin
if (Index >= Low(Classes)) and (Index <= High(Classes)) then
Result := Classes[Index].Create
else
Result := nil;
end;
← →
Kerk © (2013-01-21 23:22) [4]Конкурс у кого фантазия богаче? :)
← →
uw © (2013-01-22 00:29) [5]Dimka Maslov © (21.01.13 21:57) [3]
Тогда уж так:type
TSomeClass = class
public
constructor Create; virtual;
end;
TClassOfSomeClass = class of TSomeClass;
TSecondClass = class (TSomeClass);
TThirdClass = class (TSomeClass);
const
Classes: array[1..3] of TClassOfSomeClass = (TSomeClass, TSecondClass,
TThirdClass);
function TForm1.FormCreate(Sender: TObject);
var
SomeVar: TSomeClass;
begin
SomeVar := Classes[2].Create;
SomeVar.Free;
end;
end.
← →
uw © (2013-01-22 00:37) [6]Я хотел написать:
function CreateClass(Index: Integer): TClassOfSomeClass;
begin
Result := Classes[Index];
end;
function TForm1.FormCreate(Sender: TObject);
var
SomeVar: TSomeClass;
begin
SomeVar := CreateClass(2).Create;
SomeVar.Free;
end;
← →
Dimka Maslov © (2013-01-22 10:11) [7]
> uw © (22.01.13 00:37) [6]
Дополнительная проверка на нахождение индекса в диапазоне и последующая проверка указателя на объект, а не на метакласс не помешает.
← →
uw © (2013-01-22 10:43) [8]Да ведь по-любому всё будет охвачено оператором try, а автор хочет, чтобы ему создали класс, а не экземпляр :)
← →
Dimka Maslov © (2013-01-22 13:13) [9]
> uw © (22.01.13 10:43) [8]
Автор путает понятия «класс» и «объект», но судя по коду ему надо таки объект определённого класса, на этапе компияции неизвестного.
← →
uw © (2013-01-22 15:32) [10]То, что автор путает, это понятно. Но из нашего обсуждения напрашиваются два вопроса:
1. А надо ли в Delphi делать дополнительные проверки, если синтаксис позволяет определять ограниченные типы вроде TType = 1..3, включать соответствующие опции компилятора и пользоваться механизмом исключений?
2. А есть ли смысл пользоваться функциями, возвращающими метаклассы, как я это предложил выше? Я, например, воспользовался этим всего-то один раз, и то можно было возвращать экземпляр. Но ведь так круто!
← →
Дмитрий С © (2013-01-22 16:14) [11]
> Автор путает понятия «класс» и «объект»,
Тогда уж "экземпляр класса", а не "объект".
← →
icWasya © (2013-01-22 16:15) [12]Варианты, предлагаемые в [2],[3],5] и автором, предполагают, что список классов не меняется, или при каждом таком изменении надо будет переписывать функцию CreateClass. Если это не напрягает - то флаг в руку.
Подход применяемый в Дельфи заключается в том, что функция CreateClass и обвязка вокруг неё пишется один раз в отдельном модуле, который знать не знает, объекты каких классов будут создаваться. А модули, в которых находятся объявления классов, только регистрируют свои классы для использования в этой системе.
← →
Ega23 © (2013-01-22 16:24) [13]
> Подход применяемый в Дельфи заключается в том, что функция
> CreateClass и обвязка вокруг неё пишется один раз в отдельном
> модуле, который знать не знает, объекты каких классов будут
> создаваться. А модули, в которых находятся объявления классов,
> только регистрируют свои классы для использования в этой
> системе
Можно и без регистрации, см. [1]
← →
Dimka Maslov © (2013-01-22 16:39) [14]
> uw © (22.01.13 15:32) [10]
1. Даже в ограниченный тип при желании можно неправильный индекс, который никакой проверкой не проверится. К тому же, лучше получить исключение в прогнозируемом месте, а не ждать, когда неправильный адрес уйдёт неизвестно куда.
2. Тип, возвращаемый функцией, метакласс или готовый объект сильно зависит от поставленной задачи. К тому же для метаклассов неприменимы операторы is и as, и если нам захочется проверить, что вернула функция, нам всё равно придётся создавать объект. А для данного примера это вообще непринципиально.
← →
uw © (2013-01-22 18:05) [15]1. Даже в ограниченный тип при желании можно неправильный индекс, который никакой проверкой не проверится.
Даёт исключение, если включить Check Range.
← →
Dimka Maslov © (2013-01-22 18:19) [16]
> uw © (22.01.13 18:05) [15]
Даже с включенным чекрейджем, при желании, можно выйти за границы массива и не получить исключение, а получить битый указатель, который даст исключение в другом месте.
← →
uw © (2013-01-22 19:56) [17]Интересное желание. Приведи, пожалуйста, пример, как ты это будешь делать.
← →
Dimka Maslov © (2013-01-22 21:05) [18]type
PClassArray = ^TClassArray
TClassArray = array[1..3] of TClass;
PClassArrayEx = ^TClassArrayEx;
TClassArrayEx = array[1..100] of TClass;
var
T: TClassArray;
P: PClassArrayEx;
P := PClassArrayEx(Pointer(@T));
P^[4].Create;
← →
uw © (2013-01-22 21:51) [19]Ну что ж, теперь я понял, зачем ты делаешь дополнительные проверки :)
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2013.06.02;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.003 c