2009-02-12 71 views
9

假设我的德尔福类看起来是这样的:我应该如何释放Delphi 7析构函数中的对象数组?

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?我需要做什么吗?

回答

12

您需要遍历并释放每个创建的对象。

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

我会用TList代替更加动态的方法。你甚至可以使用一个TObjectList来清空列表中的所有项目。

+0

是的,我在一个循环中调用TMySubInfo.Create来创建它们。一旦创建,我不需要添加或删除任何 - 这就是为什么我选择了一个简单的数组。 – Blorgbeard 2009-02-12 23:54:27

+0

另外,假设我将它们放在一个循环中,那么是否还需要SetLength(0)? – Blorgbeard 2009-02-12 23:55:49

2

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

+1

或在德尔福创建 – 2009-02-13 00:40:29

+0

其实,不在德尔福。首先,接口被引用计数,分配给它们的对象被自动释放。其次,记录可以使用`创建`来初始化,但是你不会'释放'它们。 – user 2017-12-15 17:06:04

3

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

9

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

destructor TMyInfo.Destroy; 
var 
    I: Integer; 
begin 
    for I:= Low(SubInfo) to High(SubInfo) do 
    SubInfo[I].Free; 
    SetLength(SubInfo, 0); 
    inherited; 
end; 
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这样的动态数组字段会自动释放。它与接口,字符串和Variant字段的工作方式相同。

5

同意以上所有建议,但我想添加一个(固然有点肛门)的建议,您总是会优先于Free方法调用FreeAndNil()过程。

您迟早会意外地访问您已经释放的对象。如果你有习惯FreeAndNil-ing的一切,那么你会得到一个包含问题的直线a/v。如果你只是释放了这个对象,你可能会在一段时间之后得到一个神秘的,显然没有连接的失败......

这在析构函数的上下文中可能看起来像是在执行,就像这里一样。好吧,这有点儿,但是无论是在任何地方都可以,或者根本不会。

4

它也是肛门,但希望以相反的顺序释放的创造,例如:

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

我查看创建和销毁如parethesis(),尽管它使豆蔻实际执行性差异。 Bri