Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Создать класс по имени


Влад ©   (2012-05-14 23:19:00) 

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private    { Private declarations }
 public     { Public declarations }
 end;

 TBase = class
 public
   procedure Show; virtual;
 end;

 TChild = class(TBase)
 public
   procedure Show; override;
 end;

var
 Form1: TForm1;

implementation
{$R *.dfm}

procedure TBase.Show;
begin
 ShowMessage('{ TBase }');
end;

procedure TChild.Show;
begin
 inherited;
 ShowMessage('{ TChild }');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 D: TBase;

 function CreateByName(sName: string):TBase;
 begin
// Classes.FindClass требует TPersistent
// то есть:
// NewClass: TPersistentClass;
// NewClass := FindClass(sName);
// и т.п.

   Result := Как тут создать экземпляр по имени, именно от TObject?
// ( можно TThread, но это все равно, он от объекта тоже сразу идет)?

 end;

begin
//что бы сработало напрмер такое
  D := CreateByName('TBase');
  D.Show;
  D := CreateByName('TChild');
  D.Show;
end;


AV   (2012-05-15 10:13:00) [1]


> А в чем копался?
+
> Что тут нетривиального-то?

в чем.. как достучаться до класса..
Tobject реализацию, как обращения ходят в файндкласс


> Омлет ©   (15.05.12 09:30) [8]
>
> Хотя, начиная с 2010 есть TRttiContext.FindType. После чего
> можно вызвать конструктор TRttiInstanceType.GetMethod('Create').
> Invoke(...).

Да, тоже такое находил на каком-то форуме
но D7, к сожалению, у самого.


Омлет   (2012-05-15 09:30:00) [2]

Хотя, начиная с 2010 есть TRttiContext.FindType. После чего можно вызвать конструктор TRttiInstanceType.GetMethod('Create').Invoke(...).


icWasya   (2012-05-15 09:29:00) [3]

>AV ©   (15.05.12 08:45) [2]
Когда классов пять - десять, то можно и перебором.

А если делать так, как советует Loginov Dmitry[1], то к базовому классу надо добавить виртуальный конструктор.

TBase = class
public
  constructor Create; virtual; //<<======
  procedure Show; virtual;
end;


И, если в классах наследниках конструкторы не тривиальные, не забывать у них Override;


Омлет   (2012-05-15 09:17:00) [4]

Пардон, не дочитал.

>  Как тут создать экземпляр по имени, именно от TObject?

тогда 1.


Palladin   (2012-05-15 09:17:00) [5]


> AV ©   (15.05.12 08:45) [2]

А в чем копался?


Ega23   (2012-05-15 09:14:00) [6]


> покопался-покопался, а задачка не так уж тривиальна, имхо:)


Что тут нетривиального-то? Либо что-то типа [1], либо RegisterClass


Омлет   (2012-05-15 09:14:00) [7]

RegisterClass
RegisterClasses
GetClass
FindClass
F1


AV   (2012-05-15 08:45:00) [8]

покопался-покопался, а задачка не так уж тривиальна, имхо:)

проще и понятнее тогда тупо

function CreateByName(sName: string):TBase;
begin
  Result := nil;
  if sName = 'TBase' then
     Result := TBase.Create;
  if sName = 'TChild' then
     Result := TChild.Create;
end;


Loginov Dmitry   (2012-05-14 23:55:00) [9]

Используйте собственный механизм для регистрации классов. Сгодится обычный TStringList.

Как-то так:


type
 TBaseClass = class of TBase;

procedure TForm1.Button1Click(Sender: TObject);
var
 AList: TStringList;
 AClass: TBaseClass;
 Obj: TBase;
begin
 // Создание списка классов
 AList := TStringList.Create;

 // Регистрация своего класса в списке
 AList.AddObject(TBase.ClassName, TObject(TBase));
 AList.AddObject(TChild.ClassName, TObject(TChild));

 // Поиск класса по его имени
 AClass := TBaseClass(AList.Objects[AList.IndexOf('TBase')]);
 Obj := AClass.Create;
 Obj.Show;
 Obj.Free;

 AClass := TBaseClass(AList.Objects[AList.IndexOf('TChild')]);
 Obj := AClass.Create;
 Obj.Show;
 Obj.Free;

 AList.Free;
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо