今天我们继续在 Delphi 的世界里,继续上一节提过对象的永续储存,今天主要说说永续存储的方式,这点就像我们日常生活中对物品的保存与复制,有着各种巧妙的方式。
一、复制对象变量和 Assign 方法
复制对象变量就如同给物品贴标签,当你复制一个对象变量时,只是多了一个指向该对象的 “标签”,并非真正复制了对象本身。而 Assign 方法则像是一套特定的复制规则,它能根据对象的特性,将一个对象的属性值复制到另一个对象中,就像按照一定的标准把一个盒子里的东西转移到另一个盒子里。
例如,有两个 TButton 对象 Button1 和 Button2,使用 Button2 := Button1,只是让 Button2 指向 Button1 所指的对象;而 Button2.Assign (Button1),则会将 Button1 的属性(如 Caption、Color 等)复制给 Button2。
var
Button1, Button2: TButton;
begin
Button1 := TButton.Create(nil);
Button2 := TButton.Create(nil);
Button1.Caption := '按钮1';
// 复制对象变量
Button2 := Button1; // 此时Button2和Button1指向同一个对象
// 使用Assign方法
Button2.Assign(Button1); // 将Button1的属性复制给Button2
end;
二、Shallow Copy(浅拷贝)
浅拷贝就像复制一个文件夹的快捷方式,它只复制对象本身以及对象中包含的引用类型变量的地址,而不会复制引用类型变量所指向的对象。就好比你复制了一个指向文件的快捷方式,当原文件内容改变时,通过快捷方式打开的文件内容也会改变。
在 Delphi 中,一些对象的默认复制方式可能是浅拷贝,当对象中包含其他对象的引用时,使用浅拷贝可能会导致多个对象共享同一个内部对象,修改其中一个会影响到其他对象。
type
TMyClass = class
public
Data: TStringList;
constructor Create;
function ShallowCopy: TMyClass;
end;
constructor TMyClass.Create;
begin
inherited;
Data := TStringList.Create;
end;
function TMyClass.ShallowCopy: TMyClass;
begin
Result := TMyClass.Create;
Result.Data := Self.Data; // 浅拷贝,只复制引用
end;
三、Deep Copy(深拷贝)
深拷贝则像是把一个物品连同其内部所有东西都完整地复制一份,它不仅复制对象本身,还会复制对象中引用类型变量所指向的所有对象。这就如同你把一个盒子里的所有东西都拿出来,逐个复制后放进一个新的盒子里,原盒子和新盒子里的东西彼此独立,互不影响。
在处理包含复杂引用关系的对象时,深拷贝能保证每个对象的独立性,避免相互干扰。
type
TMyClass = class
public
Data: TStringList;
constructor Create;
function DeepCopy: TMyClass;
destructor Destroy; override;
end;
constructor TMyClass.Create;
begin
inherited;
Data := TStringList.Create;
end;
function TMyClass.DeepCopy: TMyClass;
begin
Result := TMyClass.Create;
Result.Data.Assign(Self.Data); // 深拷贝,复制内容
end;
destructor TMyClass.Destroy;
begin
Data.Free;
inherited;
end;
四、TFiler 类别
TFiler 就像一个负责物品打包与解包的总管,它在 Delphi 的永续储存机制中起到协调作用,管理着对象的存储和读取过程。它能够处理对象的序列化和反序列化,决定着对象如何被转化为可存储的形式以及如何从存储形式恢复为对象。
五、TWriter 类别
TWriter 相当于一个记录员,它负责将对象的信息按照一定的格式写入到存储介质中(如文件、流等)。它就像在给物品做详细的记录,把每个部分的信息都清晰地写下来,以便后续能够准确还原。
var
Stream: TMemoryStream;
Writer: TWriter;
MyInt: Integer;
begin
Stream := TMemoryStream.Create;
Writer := TWriter.Create(Stream, 4096);
try
MyInt := 123;
Writer.WriteInteger(MyInt); // 将整数写入流
Writer.Flush;
finally
Writer.Free;
Stream.Free;
end;
end;
六、TReader 类别
TReader 则类似于一个解读员,它能够从存储介质中读取由 TWriter 写入的信息,并根据这些信息还原出对象。它就像根据之前记录员写下的记录,一步步把物品重新组装起来,恢复其原本的样子。
var
Stream: TMemoryStream;
Reader: TReader;
MyInt: Integer;
begin
Stream := TMemoryStream.Create;
// 假设流中已有通过TWriter写入的整数数据
Reader := TReader.Create(Stream, 4096);
try
MyInt := Reader.ReadInteger; // 从流中读取整数
finally
Reader.Free;
Stream.Free;
end;
end;
最后小结
总的来说,Delphi 的永续储存机制通过这些不同的方式,实现了对象的复制、存储和还原,它们相互配合,就像一个精密的团队,确保了对象信息能够在程序运行的不同阶段被妥善处理,这在实际开发中有着非常重要的作用,让我们能够更灵活地管理和使用对象,明天我们继续!未完待续............