2009-02-12 66 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