如何解决克隆复杂对象的简单方法
我有一堂课,看起来像这样:
TCharacter = class (TData)
Images: array of T_Variable_Image;
Description: String;
Place: TPlace;
Dialogues: TSequenceData;
Abilities: array of TAbility;
Inventory: TContainer;
Journal: TJournal;
SideName: String;
Side: Integer;
Status: String;
Disabled: Boolean;
如您所见,其一半字段是其他类或记录,其中许多具有类似的复杂结构。 TCharacter从TData继承,而TData又从TPersistent继承-我认为,它的Assign方法将帮助我轻松地将TCharacter的一个实例克隆到另一个实例。 las,这并不容易。所以我的问题是-对我来说,克隆实例而不丢失任何数据或创建一个指针的最佳方法是什么?该方法会随其原始变化而改变。
解决方法
您正在寻找TPersistent.Assign/To()
方法。例如,您只需要在各个类中实现实现(可能需要进行一些调整,具体取决于您的实际类设计):
type
TData = class (TPersistent)
...
function Clone: TData;
end;
TDataClass = class of TData;
T_Variable_Image = class (TData)
...
procedure Assign(Source: TPersistent); override;
end;
TPlace = class (TData)
...
procedure Assign(Source: TPersistent); override;
end;
TSequenceData = class (TData)
...
procedure Assign(Source: TPersistent); override;
end;
TAbility = class (TData)
...
procedure Assign(Source: TPersistent); override;
end;
TContainer = class (TData)
...
procedure Assign(Source: TPersistent); override;
end;
TJournal = class (TData)
...
procedure Assign(Source: TPersistent); override;
end;
TCharacter = class (TData)
Images: array of T_Variable_Image;
Description: String;
Place: TPlace;
Dialogues: TSequenceData;
Abilities: array of TAbility;
Inventory: TContainer;
Journal: TJournal;
SideName: String;
Side: Integer;
Status: String;
Disabled: Boolean;
...
procedure Assign(Source: TPersistent); override;
end;
...
function TData.Clone: TData;
begin
Result := TDataClass(ClassType).Create;
try
Result.Assign(Self);
except
Result.Free;
raise;
end;
end;
...
procedure TCharacter.Assign(Source: TPersistent);
var
Src: TCharacter;
I : Integer;
begin
if Source is TCharacter then
begin
Src := TCharacter(Source);
for I := Low(Images) to High(Images) do
begin
Images[I].Free;
end;
SetLength(Images,Length(Src.Images));
for I := Low(Src.Images) to High(Src.Images) do
begin
Images[I] := T_Variable_Image(Src.Images[I].Clone);
end;
Description := Src.Description;
Place.Assign(Src.Place);
Dialogues.Assign(Src.Dialogues);
for I := Low(Abilities) to High(Abilities) do
begin
Abilities[I].Free;
end;
SetLength(Abilities,Length(Src.Abilities));
for I := Low(Src.Abilities) to High(Src.Abilities) do
begin
Abilities[I] := TAbility(Src.Abilities[I].Clone);
end;
Inventory.Assign(Src.Inventory);
Journal.Assign(Src.Journal);
SideName := Src.SideName;
Side := Src.Side;
Status := Src.Status;
Disabled = Src.Disabled;
end else
inherited;
end;
// implement Assign() for your other classes as needed...
,
重写类中的Assign方法,分配您引入的新字段/属性。不要忘记调用继承。 如果字段是类,则应调用其Assign方法,如果创建了这些类,请不要忘记重写其Assign方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。