![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Создать класс по имени
Влад © (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;