I have the following use-case:
At run time I have a class instance I would like to clone. For this I need to create a new instance of the same type.
Using class references this should be possible:
newInstance := TClassA(originalInstance.ClassType.Create);
This produces the right class type on the new instance. So far so good.
The problem arises when I need to execute code in the constructor. Apparently when calling Create on a class reference it always calls the basic constructor of the referenced class hierarchy, instead of the constructor of the currently instanciated class.
The following example code shows the problem. When constructing
b it outputs the right class name, but the TClassB constructor code is not executed. Rather it only executes the the TClassA constructor code.
program Project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
Classes;
type
TClassA = class
constructor Create;
end;
TClassB = class(TClassA)
constructor Create;
end;
TClassARef = class of TClassA;
constructor TClassA.Create;
begin
WriteLn('Construct A');
end;
constructor TClassB.Create;
begin
WriteLn('Construct B');
end;
var
a: TClassA;
b: TClassA;
begin
a := TClassB.Create;
WriteLn(a.ClassName);
b := TClassA(TClassARef(a.ClassType).Create);
WriteLn(b.ClassName);
end.
Expected console output:
Construct B
TClassB
Construct B
TClassB
Actual console output:
Construct B
TClassB
Construct A
TClassB
Is this intentional behaviour, or did I miss any kind of option/parameter to set?
Obviously when there is initialization code done in a constructor, having only a base constructor be executed can cause serious negative side effects.