德尔福.克隆一个对象

Wel*_*onD 3 delphi object

是否可以使用其他引用克隆对象?

这是我正在尝试做的一个例子:我有一个TLabel名字Label1.现在我想创建一个Label2,等于Label1,能够在不相互反映的情况下进行更改.

Ps:我用的TLabel是一个例子,我想复制另一个实例中的任何对象.

在下面的代码中,我尝试更改名称,但引用仍然相同,当更改其中一个时,另一个也会更改.

var
    cloneOfLabel1: TLabel;
begin
    Label1.Caption := 'label 1';
    cloneOfLabel1 := Label1;
    cloneOfLabel1.Name := 'label2';
    cloneOfLabel1.Caption := 'label 2';
    cloneOfLabel1.Left := 0;
    cloneOfLabel1.Top := Label1.Top+100;
Run Code Online (Sandbox Code Playgroud)

Yur*_*kov 8

可以为TComponent后代编写克隆函数:

function CloneComponent(aSource: TComponent): TComponent;
var mem: TMemoryStream;
begin
  mem := TMemoryStream.Create;
  try
    mem.WriteComponent(aSource);
    mem.Seek(0,soFromBeginning);
    Result := mem.ReadComponent(nil);
  finally
    mem.free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

请注意,只有发布的属性被复制这种方式,也有一些数据,组件保存通过DefineProperties.克隆了整数,浮点数,字符串,枚举和集合,但是引用可能存在问题:流式系统设计用于保存到文件并从那里读取,因此没有内存地址被转移,而是进行相当复杂的操作来转换它们到字符串路径,包括组件所有者和名称.通常,您需要流式传输所有结构,然后才会保存一些内部关系.

如果您是应该克隆的类的设计者,那么重写Assign方法似乎是更强大的解决方案.

这个TComponent流媒体解决方案的好处是:你能够克服一些任意组件而不知道它是什么类.例如,列出各种组件或一些更复杂的结构,然后获取每个组件的完整副本.

  • 实际上,@ JerryDodge这就是IDE本身如何在设计时实现组件的复制/粘贴.它将复制的组件流式传输到DFM,然后将DFM流式传输到粘贴的组件中.这是VCL和FMX支持克隆对象的唯一官方方式,无需每个类实现`TPersistent.Assign()`和/或`TPersistent.AssignTo()` (4认同)

Jer*_*dge 5

在您的代码中,您正在执行此操作:

cloneOfLabel1 := Label1;
Run Code Online (Sandbox Code Playgroud)

但是,这只是获取其指针的副本,因此它仍将引用原始.它不会复制.

你可以得到最接近的TPersistent.Assign(),需要实现以实际复制属性.TLabel没有实现Assign,因此您也不能使用它来创建克隆.

答案是你不能随意克隆对象,除非它继承TPersistent 实现Assign.即便如此,你仍然受这个Assign程序的支配,所以它只会复制那些被设计复制的属性.Name肯定不是其中之一,特别是因为不可能有两个具有相同名称的组件.实际上,即使您为组件的克隆副本设置了唯一名称,也无法通过它引用它,因为它是在运行时创建的.只能通过名称直接引用设计时组件.

在旁注中,记录可以(本质上)通过使用简单来复制:=,因为记录是值类型而不是类.但是,我确信根据你的例子,这些记录是不可能的.