5

I have a TObject reference to a instance of an unkown class. How do I call the constructor of this unknown class to create another instance of it? I know that Delphi has RTTI, but it isn't clear how to use it.

Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
neves
  • 33,186
  • 27
  • 159
  • 192

1 Answers1

10

You can't construct an object of unknown type. The compiler has to know the correct class type at compile-time so it can generate the proper code. What if the constructor requires parameters? How many? What data types? Are they passed by stack or registers? This information is important.

That being said, if the classes in question are all derived from a common base class that has a virtual constructor, THEN and ONLY THEN can you construct such objects. You can use the TObject.ClassType() method to get a reference to the class type of the existing object, type-cast it to the base class type, and call the constructor. For example:

type
  TBase = class
  public
    constructor Create(params); virtual;
  end;

  TBaseClass = class of TBase;

  TDerived1 = class(TBase)
  public
    constructor Create(params); override;
  end;

  TDerived2 = class(TBase)
  public
    constructor Create(params); override;
  end;

  ...

var
  NewObj: TBase;
begin
  if SomeObj is TBase then
    NewObj := TBaseClass(SomeObj.ClassType).Create(params);
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 2
    It's worth adding that this is the fundamental way in which `TComponent` works. As soon as you have the ClassType (say X) you can call `TComponentClass(X).Create(...)`. The DFM streaming works by finding the ClassType registered for a particular class name in the DFM and instantiating it as above. – Disillusioned Nov 07 '14 at 16:09