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

时间:2009-02-12 23:44:34

标签: 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.

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

8 个答案:

答案 0 :(得分:12)

你需要循环并释放每个创建的对象。

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

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

答案 1 :(得分:9)

您应该释放每个项目,例如

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

答案 2 :(得分:6)

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

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字段相同。

答案 3 :(得分:5)

同意上述所有建议,但我想添加一个(诚然有点肛门)推荐,你总是调用FreeAndNil()程序而不是Free方法。

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

这可能在析构函数的上下文中看起来很痴迷,就像这里一样。好的,它有点,但是无论是在任何地方还是根本没有。

答案 4 :(得分:4)

它也是肛门,但喜欢以与创作相反的顺序释放,例如:

For I := List.Count-1 downto 0 do
  List[I].Free;

我认为创造和毁灭是作为parethesis(),尽管它使得实际的执行差异变得微不足道。 BRI

答案 5 :(得分:3)

如果您通过构造函数调用创建了对象,则需要调用Free来释放它们。如果没有,你就不会。

答案 6 :(得分:2)

对于每一个新的应该是免费的。

答案 7 :(得分:0)

你能否使用Finalize