4

Delphi 4 にこのコードがあります。タイプのオブジェクトを 10 個作成しT_Charge(以下を参照)、これをTListという名前の に追加しましたmyListT_Charge型には、型の 3 つのオブジェクトへの参照があります(T_Platte以下を参照)。

10 個のオブジェクトすべてのメモリをすべて解放する正しい方法は何ですか? したがって、すべてのオブジェクトについて、、、、などのメモリとそれ自体のメモリP1を解放したいと考えています。私はすべてについて試しましたが、エラーが発生し続けます。P2P3F_TreatedmyCharge

procedure Test;
var 
  myList: TList;
  myCharge: T_Charge;
begin
  myList := TList.Create;

  for i := 0 to 9 do
  begin;
    myCharge := T_Charge.Create(...);
    myList.Add(myCharge);
  end;
  ...
end;

type
  T_Platte = class(TObject)
  private
    F_Nummer : Integer;
    F_Los    : Integer;
    F_Dicke  : Real;
    F_Lange  : Real;
    F_Breite : Real;
    F_QuenchCode : Integer;
    F_Geschwindigkeit : Real;
    F_Menge  : Integer;
    F_MengeInLos : Integer;
    F_Treated : Boolean;
  public
    constructor Create(inNummer, inLos: Integer; inDicke, inLange, inBreite, inGeschwindigkeit : Real; inQuenchCode,inMenge: Integer; inTreated: Boolean); overload;
    constructor Create(inPlatte: T_Platte); overload;
    destructor Destroy; override;

    property Nummer: Integer read F_Nummer write F_Nummer;
    property Los: Integer read F_Los write F_Los;
    property Dicke: Real read F_Dicke write F_Dicke;
    property Lange: Real read F_Lange write F_Lange;
    property Breite: Real read F_Breite write F_Breite;
    property QuenchCode : Integer read F_QuenchCode write F_QuenchCode;
    property Geschwindigkeit: Real read F_Geschwindigkeit write F_Geschwindigkeit;
    property Menge: Integer read F_Menge write F_Menge;
    property MengeInLos: Integer read F_MengeInLos write F_MengeInLos;
    property Treated: Boolean read F_Treated write F_Treated;

    function getPlattenRecord: string;
  end; // class T_Platte  

  T_Charge = class(TObject)
  private
    F_P1 : T_Platte;
    F_P2 : T_Platte;
    F_P3 : T_Platte;
    F_Treated : Boolean;
    F_Vmin : Real;
    F_Qty : Integer;
    F_RelationNext : Boolean;
  public
    constructor Create(inP1, inP2, inP3 : T_Platte; inTreated: Boolean; inVmin: Real; inQty: Integer; inRelationNext: Boolean);  overload;
    constructor Create(inCharge : T_Charge); overload;
    destructor Destroy; override;

    property P1: T_Platte read F_P1 write F_P1;
    property P2: T_Platte read F_P2 write F_P2;
    property P3: T_Platte read F_P3 write F_P3;
    property Treated : Boolean read F_Treated write F_Treated;
    property Vmin : Real read F_Vmin write F_Vmin;
    property Qty : Integer read F_Qty write F_Qty;
    property RelationNext : Boolean read F_RelationNext write F_RelationNext;

    function getChargeRecord: string;
  end; // class T_Charge


constructor T_Platte.Create(inNummer, inLos: Integer; inDicke, inLange, inBreite, inGeschwindigkeit: Real; inQuenchCode,inMenge: Integer; inTreated: Boolean);
begin
  F_Nummer := inNummer;
  F_Los := inLos;
  F_Dicke := inDicke;
  F_Lange := inLange;
  F_Breite := inBreite;
  F_Geschwindigkeit := inGeschwindigkeit;
  F_QuenchCode := inQuenchCode;
  F_Menge := inMenge;
  F_MengeInLos := 0;
  F_Treated := inTreated;
end;

constructor T_Charge.Create(inP1, inP2, inP3 : T_Platte; inTreated: Boolean; inVmin:  Real; inQty: Integer; inRelatio nNext: Boolean);
begin
  F_P1 := T_Platte.Create(inP1);
  F_P2 := T_Platte.Create(inP2);
  F_P3 := T_Platte.Create(inP3);
  F_Treated := inTreated;
  F_Vmin := inVmin;
  F_Qty := inQty;
  F_RelationNext := inRelationNext;
end;
4

6 に答える 6

8

リスト オブジェクトを解放するには、リストを作成して TList.Notify() をオーバーライドします。

procedure THotFixList.Notify(Ptr: Pointer; Action: TListNotification);
begin
  inherited;
  if Action = lnDeleted then
    Tobject(Ptr).Free;
end;

これにより、TLIst.Delete、TList.Clear、TList.Free を呼び出すたびにオブジェクトが確実に解放され、毎回自分でリストを反復する必要がなくなります。

于 2012-09-06T08:01:56.910 に答える
5

のデストラクタに次を追加しますT_Charge

destructor T_Charge.Destroy;
begin
  F_P1.Free;
  F_P2.Free;
  F_P3.Free;
  // Other code as needed
  inherited;
end;

リストを解放する前に、ループしてそれぞれを削除しますT_Charge

for i := 0 to myList.Count - 1 do
  TObject(myList[i]).Free;         // This will free the inner `T_Platt3` 
                                   // each `T_Charge` contains.
于 2012-09-05T18:32:26.953 に答える
3

type のないポインターを保持するため、項目を型キャストすることを忘れないでください。

for i := 0 to myList.Count - 1 do
begin
  T_Charge(myList[i]).Free;  // Type cast
end;
于 2012-09-05T19:00:55.470 に答える
3

TObjectList具体的には、リストがクラス インスタンスを保持する必要がある場合は、むしろその目的 ( TObjectList)を使用する必要があると思います。リストが破棄されるかリストから項目が削除されたら、含まれているすべてのクラス インスタンスを解放するようにリストに指示するTObjectListwithのコンストラクタを呼び出します。Create(True)それにもかかわらず、Ken White の回答で述べたように、T_Charge デストラクタで F_P1 などを解放する必要があります。

于 2012-09-06T12:42:55.480 に答える
2

クラスに関する知識がほとんどない: TList と TObjectList の比較

TList は保持されるため、保存されPointersているものを解放する方法がわかりませんTObject

TObjectList holsTObjectsであるため、それらを解放して自動的に実行できます

私が言える最善のことは、基本クラスまたは型宣言TObjectListの代わりに使用することです。TList

サンプル:

Wrong: TMyListOfObjects=class(TList) ...
 Good: TMyListOfObjects=class(TObjectList) ...

Wrong: MyListOfObjects:TList;
 Good: MyListOfObjects:TObjectList;

注:TListは unitclassesTObjectList宣言され、 で宣言されContnrsているため、非常に多くの人が使用TListし、何も知りません(インターネットで少し前にTObjectList読む前の私も)。TObjectList

于 2016-02-04T08:23:51.277 に答える
2

myList を破棄する前に、次のものが必要です。

for i := 0 to myList.Count - 1 do  
begin;
  TObject(myList[i]).Free
end;

T_Charge のデストラクタでは、F_P1、F_P2、および F_P3 を解放する必要があります。

于 2012-09-05T18:26:25.120 に答える