假设我的Delphi类看起来像这样:
interface type TMySubInfo = class public Name : string; Date : TDateTime; Age : Integer; end; TMyInfo = class public Name : string; SubInfo : array of TMySubInfo; destructor Destroy; override; end; implementation destructor TMyInfo.Destroy; begin // hmmm.. end; end.
要正确清理,析构函数应该包含哪些内容?这样做是否足够SetLength(SubInfo,0)
,或者我是否需要循环并释放每个TMySubInfo
?我需要做任何事情吗?
您需要循环并释放每个创建的对象.
您必须知道,声明TMySubInfo数组实际上并不创建对象.您必须稍后创建它们.
我会使用TList代替更动态的方法.你甚至可以使用一个TObjectList,它可以释放列表时释放所有项目.
你应该释放每个项目,像这样
destructor TMyInfo.Destroy; var I: Integer; begin for I:= Low(SubInfo) to High(SubInfo) do SubInfo[I].Free; SetLength(SubInfo, 0); inherited; end;
您可以按照分配对象的方式释放对象.如果通过调用类的构造函数指定了元素的值,则释放该元素引用的对象.
destructor TMyInfo.Destroy; var info: TMySubInfo; begin for info in SubInfo do info.Free; inherited; end;
它使用Delphi 2005中引入的语法.如果您有旧版本,请使用显式循环控制变量:
var i: Integer; begin for i := 0 to High(SubInfo) do SubInfo[i].Free;
你不需要SetLength
在最后打电话.SubInfo
当对象被销毁时,动态数组字段会自动释放.它的作用与interface,string和Variant字段相同.
同意所有上述建议,但我想添加一个(诚然有点肛门)建议,你总是调用FreeAndNil()程序优先于Free方法.
迟早你会不小心访问已经释放的对象.如果您有FreeAndNil-ing的习惯,那么您可以在包含问题的行上立即获得a/v.如果你只是释放了这个物体,你可能会在一段时间后得到一个神秘的,显然没有连接的故障......
这可能在析构函数的上下文中似乎是强迫性的,就像这里一样.好吧,它有点,但无论是在任何地方还是根本没有.