Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
15-1358765049
vxxv
2013-01-21 14:44
2013.06.02
Создать определенный класс.


15-1359029346
Студент
2013-01-24 16:09
2013.06.02
Колонка и микрофон.


2-1351775945
Signal
2012-11-01 17:19
2013.06.02
Кто сталкивался с нейронными сетями, помогите с алгоритмом


15-1358886602
Юрий
2013-01-23 00:30
2013.06.02
С днем рождения ! 23 января 2013 среда


6-1222503093
Cryxalis
2008-09-27 12:11
2013.06.02
как заставить INDY юзать уже занятый порт?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский