我应该如何在Delphi 7析构函数中释放一组对象?

Blo*_*ard 9 delphi memory-leaks

假设我的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.
Run Code Online (Sandbox Code Playgroud)

要正确清理,析构函数应该包含哪些内容?这样做是否足够SetLength(SubInfo,0),或者我是否需要循环并释放每个TMySubInfo?我需要做任何事情吗?

Veg*_*gar 12

您需要循环并释放每个创建的对象.

您必须知道,声明TMySubInfo数组实际上并不创建对象.您必须稍后创建它们.

我会使用TList代替更动态的方法.你甚至可以使用一个TObjectList,它可以释放列表时释放所有项目.

  • 无需调用SetLength.一旦引用计数变为0,动态数组就会自动清除. (3认同)

Ces*_*ero 9

你应该释放每个项目,像这样

destructor TMyInfo.Destroy;
var
  I: Integer;
begin
  for I:= Low(SubInfo) to High(SubInfo) do
   SubInfo[I].Free;
  SetLength(SubInfo, 0); 
  inherited;
end;
Run Code Online (Sandbox Code Playgroud)

  • SetLength(SubInfo,0); 是可选的,但是好的代码. (3认同)

Rob*_*edy 6

您可以按照分配对象的方式释放对象.如果通过调用类的构造函数指定了元素的值,则释放该元素引用的对象.

destructor TMyInfo.Destroy;
var
  info: TMySubInfo;
begin
  for info in SubInfo do
    info.Free;
  inherited;
end;
Run Code Online (Sandbox Code Playgroud)

它使用Delphi 2005中引入的语法.如果您有旧版本,请使用显式循环控制变量:

var
  i: Integer;
begin
  for i := 0 to High(SubInfo) do
    SubInfo[i].Free;
Run Code Online (Sandbox Code Playgroud)

你不需要SetLength在最后打电话.SubInfo当对象被销毁时,动态数组字段会自动释放.它的作用与interface,string和Variant字段相同.


wil*_*llw 5

同意所有上述建议,但我想添加一个(诚然有点肛门)建议,你总是调用FreeAndNil()程序优先于Free方法.

迟早你会不小心访问已经释放的对象.如果您有FreeAndNil-ing的习惯,那么您可以在包含问题的行上立即获得a/v.如果你只是释放了这个物体,你可能会在一段时间后得到一个神秘的,显然没有连接的故障......

这可能在析构函数的上下文中似乎是强迫性的,就像这里一样.好吧,它有点,但无论是在任何地方还是根本没有.