2014-03-06 31 views
1

我該如何改變我的析構函數來處理共享對象實例?如何更改Delphi析構函數來處理共享對象實例?

實施例:

type 
    TAddress = class 
    private 
     FStreet : String; 
    public 
    property street: String read FStreet write FStreet; 
    end; 

    TContract = class 
    private 
     FAddress : TAddress; 
    public 
    property address: TAddress read FAddress write FAddress; 
    destructor Destroy; override; 
    end; 

    Array_Of_TContract = array of TContract; 

    TCustomer = class 
    private 
     FContracts : Array_Of_TContract; 
    public 
    property contracts: Array_Of_TContract read FContracts write FContracts; 
    destructor Destroy; override; 
    end; 

implementation 

    destructor TCustomer.Destroy; 
    var 
     I: Integer; 
    begin 
     for I := 0 to System.Length(FContracts)-1 do 
     SysUtils.FreeAndNil(FContracts[I]); 
     System.SetLength(FContracts, 0); 
     inherited Destroy; 
    end; 

    destructor TContract.Destroy; 
    var 
     I: Integer; 
    begin 
     SysUtils.FreeAndNil(FAddress); 
     inherited Destroy; 
    end; 

begin 
    Try 
    //address 
    myAddress := TAddress.Create; 
    myAddress.street := 'My Street'; 

    //First contract 
    SetLength(myContracts, Length(myContracts)+1); 
    FirstContract := TContract.Create; 
    FirstContract.address := myAddress; //<- 
    myContracts[0] := FirstContract; 

    //Second contract 
    SetLength(myContracts, Length(myContracts)+1); 
    SecondContract := TContract.Create; 
    SecondContract.address := myAddress; //<- 
    myContracts[1] := SecondContract; 

    //Single customer 
    myCustomer := TCustomer.Create; 
    myCustomer.contracts := myContracts; 

    myCustomer.Free; 

    self.Close; 
    Except 
    On e: exception do begin 
     ShowMessage(e.Message); 
    end; 
    End; 

end; 

釋放myCustomer(和內存泄漏)時的結果是無效的指針操作。

(創建每個TContract單獨TAddress對象是不是在我的情況選擇)

回答

0

我寧願不共享聯繫人之間的相同地址的實例。但由於代碼是自動生成的,我猜這不是一個選項。

你可以保持已釋放引用的軌跡:

AlreadyFreed := TList <Pointer>.Create; 
for I := 0 to System.Length(FContracts)-1 do 
    begin 
    if not AlreadyFreed.Contains(FContracts[I]) then 
    begin 
    FContracts[I].Free; 
    AlreadyFreed.Add(Pointer(FContracts[I])); 
    end; 
    end; 
1

的情況取決於應用程序的結構來處理這種最好的方式。根據示例,我會將所有地址添加到通用對象列表,然後將地址引用傳遞給TContract的實例。對於合同,如果它們不是唯一的,你可以使用類似的方法。 另一種方法是使用地址接口,然後將其分配給合同實例,最後是零。 第三個選項是複製作業。我認爲這是處理這種情況的最低效方式,但在任何情況下都能保證工作。 希望這些提供了一些想法。

+0

個人更喜歡界面選項 - 它有效地爲您實現引用計數和垃圾收集 –

相關問題