Форум: "Основная";
Текущий архив: 2002.07.25;
Скачать: [xml.tar.bz2];
ВнизДинамическое создание классов Найти похожие ветки
← →
Давид (2002-07-11 16:42) [0]Хотелось бы узнать, существует ли способ динамически создать объект определенного класса в Дельфи. Представьте себе, что в есть список пользовательских классов (Class1, Class2, ...) и, в зависимости от выбора, программа создает объект выбранного класса. Заранее благодарю за все предложения по данной проблеме.
Давид
← →
Skier (2002-07-11 16:48) [1]>Давид
http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1026125231&n=0
← →
Давид (2002-07-11 17:31) [2]> Skier
Честно говоря, получается не так как хотелось бы. У меня есть классы Class1, Class2, ..., которые имеют общего предка - класс TFormat = class of TPersistent. Пользователь выбирает, на пример, "Class2". В программе я регистрирую классы Class1, Class2, ... и описываю переменные
MyClass: TClass;
MsgObj: TObject;
Затем делаю
MyClass := GetClass("Class2");
MyObj := MyClass.Create;
Логично было бы, если бы вызывался метод Create класса Class2, но вызывается TFormat.Create.
← →
Skier (2002-07-11 17:34) [3]>Давид
MyClass: TFormat;
MsgObj: Class2;
.......................
MyClass := GetClass("Class2");
if MyClass <> nil then MyObj := MyClass.Create;
← →
Давид (2002-07-11 17:41) [4]> Skier
Вся проблема в строке MsgObj: Class2. Я не хочу описывать переменные всех классов. Вместо этого, хотелось бы создать переменную общего типа и потом изменить тип. В таком случае получилась бы программа, не зависящая от добавления новых классов.
Давид
← →
Skier (2002-07-11 17:45) [5]>Давид
MyClass: TFormat;
MsgObj: TPersistent;
.......................
MyClass := GetClass("Class2");
if MyClass <> nil then MyObj := MyClass.Create;
← →
Давид (2002-07-11 18:13) [6]> Skier
Так плохо. В строке MyClass := GetClass("Class2") Дельфи дает ошибку. Надо писать MyClass := TFormat(GetClass("Class2")), но тогда MyObj := MyClass.Create вызывает Create класса TFormat, а не Class2.
Давид
← →
Skier (2002-07-11 18:15) [7]>Давид
Давай код полностью. Как ты всё это делаешь.
← →
reonid (2002-07-11 18:23) [8]2 Давид
сделай конструктор виртуальным
← →
Давид (2002-07-11 18:23) [9]> Skier
Могу отправить по e-mail (kozhanov@newmail.ru)? Не хочу засорять форум.
Давид
← →
Skier (2002-07-11 18:25) [10]>reonid
Да какой, виртуальным ! Он, блин, говорит, что у
него Delphi ругается на строку MyClass := GetClass("Class2").
Какие уж тут конструкторы.
В общем - всё запушено...:(
← →
Skier (2002-07-11 18:26) [11]>Давид
Ты уж его и так засорил.
Давай высылай...
← →
reonid (2002-07-11 18:30) [12]Всё правильно у него ругается.
GetClass.Create возвращает TPersistent, а у него TFormat.
А с виртуальным конструктором
TFormat(GetClass("Class2")).Create;
будет правильно работать
← →
MBo (2002-07-11 18:31) [13]procedure TForm1.Button1Click(Sender: TObject);
type
TWCClass = class of TWinControl;
var
Obj:TWinControl;
ObjClass:TWCClass;
begin
RegisterClass(TButton);
RegisterClass(TEdit);
ObjClass:=TWCClass(GetClass(edit1.text));
if ObjClass<>nil then begin
Obj:=ObjClass.Create(self);
Obj.Parent:=self;
Obj.SetBounds(10,10,100,20);
end;
end;
← →
Skier (2002-07-11 18:32) [14]>reonid
А как объявлен TFormat - посмотри.
← →
Давид (2002-07-11 19:02) [15]> reonid
С виртуальным конструктором, к сожалению, не получается из-за различия в описании конструкторов. Даю описание классов:
TFormat = class (TPersistent)
constructor Create(aParam1, aParam2: String);
TClass1 = class (TFormat)
constructor Create();
В конструкторе класса TClass1 вызывается конструктор родительского класса: inherited Create(aParam1, aParam2), а параметры aParam1, aParam2 подгружаются динамически из include-файлов во время компиляции.
← →
Skier (2002-07-11 19:07) [16]>Давид
> а параметры aParam1, aParam2 подгружаются динамически из
> include-файлов во время компиляции.
??? Я в замешательстве :)
← →
Давид (2002-07-11 20:35) [17]> reonid
Я попробовал с виртуальным конструктором маленький тест. Но что-то не так. Вот код
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TBasisClass = class(TPersistent)
constructor Create(); virtual;
public
Name: String;
end;
TChildClass = class(TBasisClass)
constructor Create(); override;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
constructor TBasisClass.Create();
begin
inherited Create();
end;
constructor TChildClass.Create();
begin
Name := "David";
inherited Create();
end;
procedure TForm1.Button1Click(Sender: TObject);
var
MyObj: TObject;
begin
// Здесь во время выполнения получаю ошибку
MyObj := TBasisClass(GetClass("TChildClass")).Create;
ShowMessage((MyObj as TBasisClass).Name);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
RegisterClasses([TBasisClass, TChildClass]);
end;
end.
← →
Давид (2002-07-11 20:55) [18]Все, нашел в чем собака зарыта. Если кому-то еще интересно, вот исправленный код
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TClassRef = class of TBasisClass;
TBasisClass = class (TPersistent)
constructor Create(); virtual;
public
Name: String;
end;
TChildClass = class(TBasisClass)
constructor Create(); override;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
constructor TBasisClass.Create();
begin
inherited Create();
end;
constructor TChildClass.Create();
begin
Name := "David";
inherited Create();
end;
procedure TForm1.Button1Click(Sender: TObject);
var
MyObj: TObject;
begin
MyObj := TClassRef(GetClass("TChildClass")).Create;
ShowMessage((MyObj as TBasisClass).Name);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
RegisterClasses([TBasisClass, TChildClass]);
end;
end.
Всем огромное спасибо. Тема закрыта.
Давид
← →
psvital (2002-07-11 21:11) [19]> Давид
Лови пример, он работает.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
type
TmyBasic = class(TPersistent)
public
constructor Create; virtual;
function GetName :string; virtual;
end;
TMyClass = class(TmyBasic)
public
constructor Create; override;
function GetName :string; override;
end;
procedure TForm1.Button1Click(Sender: TObject);
var Instance :TPersistentClass;
Obj :TMyBasic;
begin
Instance := GetClass("TMyClass");
Obj := TMyBasic(Instance.NewInstance);
MessageBox(Handle, PChar(obj.GetName), "Test", MB_OK);
Obj.Free;
end;
{ TmyBasic }
constructor TmyBasic.Create;
begin
//
end;
function TmyBasic.GetName: string;
begin
Result := "TmyBasic";
end;
{ TMyClass }
constructor TMyClass.Create;
begin
inherited;
//
end;
function TMyClass.GetName: string;
begin
Result := "TMyClass";
end;
initialization
RegisterClasses([TMyBasic, TMyClass]);
end.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.07.25;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.006 c