Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.07.25;
Скачать: CL | DM;

Вниз

Динамическое создание классов   Найти похожие ветки 

 
Давид   (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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.012 c
3-81140
kires
2002-07-02 14:59
2002.07.25
русский текст


3-81157
sevylor
2002-07-04 07:17
2002.07.25
Insert in Access


1-81218
MARcoDEN
2002-07-14 10:33
2002.07.25
Как вытаскивать определенное значение из HTML страницы


14-81438
Awex
2002-06-27 12:15
2002.07.25
Задача...


14-81444
Ghostlady
2002-06-27 13:05
2002.07.25
Как отправить SMS сообщение через радиомодем?