lyborko
lyborko

Reputation: 2619

How to call constructor of given instance?

My first object is TGoodFairy (TObject) and it has own children FChildren (TList). There is Assign procedure, which makes copy of any TGoodFairy and its children.

The second object is TBadFairy which is descendant of TGoodFairy.

I am struggling how to use Assign method of the TBadFairy to create TBadFairy children. I would like to use ClassType in connection with Create, in order to create right children for TBadFairy (for now only TGoodFairy children are created)

  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;

Upvotes: 3

Views: 272

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595742

Try something more 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;

Upvotes: 5

Related Questions