Создать объект, зная его имя класса

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Создать объект, зная его имя класса

Сообщение Climber » 28.01.2010 12:57:21

У меня есть некий класс TMyForm, потомок TForm. Он регистрируется через RegisterClass(TMyForm).
Мне нужно в коде создать экземпляр класса по его имени. Искал в интернете, как это можно сделать, везде приводятся решения для стандартных компонентов, например, так:
Код: Выделить всё
TForm(GetClass(ClassName)).Create(Application);
Но этот код создаст объект TForm, а не TMyForm. Или я чего-то не понимаю?
Кстати, в моем случае вышеприведенная строка вызывает Access Violation, причем я не очень понял, почему. GetClass(ClassName) возвращает не nil.
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Создать объект, зная его имя класса

Сообщение AbakAngelSoft » 28.01.2010 13:17:44

Указанная строка создаст экземпляр найденного класса!
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Re: Создать объект, зная его имя класса

Сообщение Climber » 28.01.2010 14:00:33

А, ну может быть, я тут путаюсь все время. А Access Violation откуда?
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Создать объект, зная его имя класса

Сообщение AbakAngelSoft » 28.01.2010 14:08:32

смотрите отладчиком процесс создания вашей формы
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Re: Создать объект, зная его имя класса

Сообщение Climber » 29.01.2010 11:03:21

Чего-то я все-таки не понимаю.
Вот код:
Код: Выделить всё
type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

const
   MyClassName = 'TForm1';

implementation

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  obj: TPersistent;
begin
try
   if GetClass(MyClassName) <> nil then
      begin
        { объект создается либо этой строкой, либо следующей }
        obj:=TForm(GetClass(MyClassName)).Create(Application);    // Если создавать этой строкой, то тут возникает AV
        obj:=GetClass(MyClassName).Create;    // Если создавать этой строкой, то AV возникает при вызове Show;
        TForm(obj).Show;
        Obj.Free;
      end;
except
   on E:Exception do
     ShowMessageFmt('Класс: %s'#10'Текст: %s', [E.ClassName, E.Message]);
end;
end;

initialization
  {$I unit1.lrs}

  RegisterClass(TForm1);

end.
Что тут не так?
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Создать объект, зная его имя класса

Сообщение AbakAngelSoft » 29.01.2010 11:27:24

Climber писал(а):obj:=GetClass(MyClassName).Create; // Если создавать этой строкой, то AV возникает при вызове Show;
TForm(obj).Show;

ни в коем случае - здесь вызывается не тот конструктор.
первый вариант вроде должен сработать - сейчас попробую у себя
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Re: Создать объект, зная его имя класса

Сообщение Climber » 29.01.2010 11:42:45

AbakAngelSoft писал(а):
Climber писал(а):obj:=GetClass(MyClassName).Create; // Если создавать этой строкой, то AV возникает при вызове Show;
TForm(obj).Show;

ни в коем случае - здесь вызывается не тот конструктор.
Это был жест отчаяния. :( Собственно, меня тут смущает не AV при вызове Show, а то, что просто Create класса TPersistent вызывается, а Create(Owner: TComponent) класса TForm - нет...
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Создать объект, зная его имя класса

Сообщение AbakAngelSoft » 29.01.2010 11:46:18

Естественно!!!
Код: Выделить всё
TForm(...).Create

аналогично
Код: Выделить всё
var Form: TForm;
Form.Create

для создания нужно вызывать конструктор который находится в классе!!!
Код: Выделить всё
  TFormClass = class of TForm;
  TFormClass(...).Create
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Re: Создать объект, зная его имя класса

Сообщение Climber » 29.01.2010 12:28:12

Спасибо! На такой ерунде застрял, мог бы и сам догадаться... :oops:
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Создать объект, зная его имя класса

Сообщение AbakAngelSoft » 29.01.2010 13:00:08

Я тоже долго не мог понять!
Вроде все на поверхности, но строчка
Код: Выделить всё
obj := TForm(...).Create

выглядит как правильная. Ведь все привыкли к записи
Код: Выделить всё
obj := TForm.Create

а ведь в данном случает это приведение типов а не ссылка на класс - вот и застопорились.
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Re: Создать объект, зная его имя класса

Сообщение Climber » 29.01.2010 13:48:50

Хм...
А вот это -
Код: Выделить всё
  TFormClass = class of TForm;
  TFormClass(...).Create

Это разве не приведение типов? Внутри скобок - ссылка на класс, а снаружи - приведение?
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Создать объект, зная его имя класса

Сообщение AbakAngelSoft » 29.01.2010 14:08:07

TFormClass(...) это приведение к типу класс, а TForm(...) приведение к типу объект!
объект и класс, в некотором роде, сущности различные. :)
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 47

Рейтинг@Mail.ru