Решение Александра хорошее, но в определенных ситуациях его недостаточно. Предположим, вы хотите установить класс TClassFactory, в котором ссылки TClass могут храниться во время выполнения и произвольное количество экземпляров, полученных позже.
Такая фабрика классов никогда не узнает ничего о фактических типах классов, которые она содержит, и, следовательно, не может привести их к соответствующим мета-классам. Для вызова правильных конструкторов в таких случаях будет работать следующий подход.
Во-первых, нам нужен простой демонстрационный класс (не обращайте внимания на публичные поля, это только для демонстрационных целей).
interface
uses
RTTI;
type
THuman = class(TObject)
public
Name: string;
Age: Integer;
constructor Create(); virtual;
end;
implementation
constructor THuman.Create();
begin
Name:= 'John Doe';
Age:= -1;
end;
Теперь мы создаем объект типа THuman исключительно с помощью RTTI и с правильным вызовом конструктора.
procedure CreateInstance();
var
someclass: TClass;
c: TRttiContext;
t: TRttiType;
v: TValue;
human1, human2, human3: THuman;
begin
someclass:= THuman;
// Invoke RTTI
c:= TRttiContext.Create;
t:= c.GetType(someclass);
// Variant 1a - instantiates a THuman object but calls constructor of TObject
human1:= t.AsInstance.MetaclassType.Create;
// Variant 1b - same result as 1a
human2:= THuman(someclass.Create);
// Variant 2 - works fine
v:= t.GetMethod('Create').Invoke(t.AsInstance.MetaclassType,[]);
human3:= THuman(v.AsObject);
// free RttiContext record (see text below) and the rest
c.Free;
human1.Destroy;
human2.Destroy;
human3.Destroy;
end;
Вы обнаружите, что объекты "human1" и "human2" были инициализированы нулем, то есть Name = '' и Age = 0, что не является тем, что мы хотим. Вместо этого объект human3 содержит значения по умолчанию, предоставленные в конструкторе THuman.
Обратите внимание, однако, что этот метод требует, чтобы ваши классы имели методы конструктора без параметров. Все вышеизложенное не было задумано мной, но объяснено блестяще и более подробно (например, часть c.Free) в Техническом уголке Роба Лава .