How do I call the constructor of a given instance?
My first object TGoodFairy
(TObject) and it has its own children FChildren
(TList). There is a procedure Assign
that makes a copy of any TGoodFairy and its children.
The second object is that TBadFairy
which is a descendant of TGoodFairy.
I am struggling how to use TBadFairy's Assign method to create TBadFairy children. I would like to use the ClassType in conjunction with Create to create the correct children for TBadFairy (only TGoodFairy children have been created so far)
TGoodFairy = class (TObject)
private
FChildren:TList;
FName:string;
public
constructor Create;
destructor Destroy; override;
procedure Assign(Source:TGoodFairy);
published
property Name:string read FName write FName;
end;
TBadFairy = class (TGoodFairy)
procedure Assign(Source:TBadFairy);
end;
------------------------
constructor TGoodFairy.Create;
begin
inherited;
FChildren:=TList.Create;
end;
destructor TGoodFairy.Destroy;
var i:integer;
begin
for i:=0 to FChildren.Count-1 do TGoodFairy(FChildren[i]).Free;
FChildren.Clear;
FChildren.Free;
inherited;
end;
procedure TGoodFairy.Assign(Source:TGoodFairy);
var i:integer;
f:TGoodFairy;
C:TClass;
begin
FName:=Source.Name;
for i:=0 to Source.FChildren.Count-1 do
begin
//C := Source.ClassType;
//f := C.Create;
f := TGoodFairy.Create; //<-- this should be parametrized somehow
f.Assign(Source.FChildren[i]);
FChildren.Add(f);
end;
end;
procedure TBadFairy.Assign(Source:TBadFairy);
begin
inherited Assign(Source);
end;
+3
source to share
1 answer
Try something else like this:
type
TFairy = class(TObject)
private
FChildren: TObjectList;
FName: string;
public
constructor Create; virtual;
destructor Destroy; override;
procedure Assign(Source: TFairy); virtual;
published
property Name: string read FName write FName;
end;
TFairyClass = class of TFairy;
TGoodFairy = class(TFairy)
end;
TBadFairy = class(TFairy)
end;
constructor TFairy.Create;
begin
inherited;
FChildren := TObjectList.Create(True);
end;
destructor TFairy.Destroy;
begin
FChildren.Free;
inherited;
end;
procedure TFairy.Assign(Source: TFairy);
var
i: integer;
f, child: TFairy;
begin
FName := Source.Name;
FChildren.Clear;
for i := 0 to Source.FChildren.Count-1 do
begin
child := TFairy(Source.FChildren[i]);
f := TFairyClass(child.ClassType).Create;
try
f.Assign(child);
FChildren.Add(f);
except
f.Free;
raise;
end;
end;
end;
+5
source to share