Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Free eines unbekannten Objektes (https://www.delphipraxis.net/120404-free-eines-unbekannten-objektes.html)

sirius 10. Sep 2008 20:24

Re: Free eines unbekannten Objektes
 
Zitat:

Zitat von olee
Das merkwürdige an der ganzen sache ist aber noch, dass selbst wenn ich
Delphi-Quellcode:
  T3DObj(WorldActor).free;
  If T3DObj(WorldActor) <> nil then [...]
benutze gibt "T3DObj(WorldActor) <> nil" true zurück.

Das ist nicht merkwürdig, das ist nur logisch und auch nicht anders machbar, siehe Post #6.

olee 10. Sep 2008 20:36

Re: Free eines unbekannten Objektes
 
ja aber selbst als ich das hier verwendet habe:
Delphi-Quellcode:
  For i := 0 To Objects.Count - 1 Do
  begin
    T3DObj(Objects[i]).Free;
    Objects[i] := nil;
  end;
aber da fällt mir ein:

Man muss bedenken Objects[i] ist nicht WorldActor aber hat den gleichen wert

olee 10. Sep 2008 20:47

Re: Free eines unbekannten Objektes
 
Ma ne frage zur TObjectList:

Der gibt mit ObjectList.Items[X] ein TObject zurück.

Muss ich das einfach casten?

DeddyH 10. Sep 2008 20:57

Re: Free eines unbekannten Objektes
 
Sicher.

automatix 11. Sep 2008 09:19

Re: Free eines unbekannten Objektes
 
Hallo!

Dies funktioniert, wie schon geschrieben, nicht.

Delphi-Quellcode:
  TKlasse1(list[i]^).Free;
Ich habe es bisher fast immer vermeiden können in Delphi mit Pointern zu arbeiten und muss daher i.d.R. immer erst probieren, wann eine Pointer Dereferenzierung mittel ^ nötig ist und wann nicht.

Ich habe hier mal ein paar Möglichkeiten runtergetippt.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Contnrs,
  Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

  TKlasse1 = class(TObject)
  public
     constructor Create;
    destructor Destroy; override;
  end;

  TKlasse2 = class(TKlasse1)
  public
     constructor Create;
    destructor Destroy; override;
  end;

  TKlasse3 = class(TKlasse2)
  public
     constructor Create;
    destructor Destroy; override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
   MAX_OBJ = 5;

procedure TForm1.FormCreate(Sender: TObject);
begin
   Randomize;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   i: Integer;
  list: TList;
begin
   list := nil;
  try
     list := TList.Create;

    for i := 0 to Pred(MAX_OBJ) do begin
      case Random(3) of
      0: list.Add(TKlasse1.Create);
      1: list.Add(TKlasse2.Create);
      2: list.Add(TKlasse3.Create);
      end;
    end;

    // ...

    for i := 0 to Pred(list.Count) do
      TKlasse1(list[i]).Free;
      //(list[i] as TKlasse1).Free;              // Operator ist auf diesen Operandentyp nicht anwendbar
      //(TObject(list[i]) as TKlasse1).Free; // :-)

    MessageDlg('Fertig mit Free', mtInformation, [mbOk], 0);
  finally
    FreeAndNil(list);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
   i: Integer;
  list: TObjectList;
begin
   list := nil;
  try
     list := TObjectList.Create;

    for i := 0 to Pred(MAX_OBJ) do begin
      case Random(3) of
      0: list.Add(TKlasse1.Create);
      1: list.Add(TKlasse2.Create);
      2: list.Add(TKlasse3.Create);
      end;
    end;

    // ...

    for i := 0 to Pred(list.Count) do
      TKlasse1(list[i]).Free;                  // Hier sind beide Varianten möglich
      // (list[i] as TKlasse1).Free;

    MessageDlg('Fertig mit Free', mtInformation, [mbOk], 0);
  finally
     // Hier knallt es, weil durch OwnsObjects = True der Destruktor der Liste
    // versucht die schon freigegebenen Objekte noch einmal freizugeben
    FreeAndNil(list);
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
   i: Integer;
  list: TObjectList;
begin
   list := nil;
  try
     list := TObjectList.Create;
    list.OwnsObjects := False;

    for i := 0 to Pred(MAX_OBJ) do begin
      case Random(3) of
      0: list.Add(TKlasse1.Create);
      1: list.Add(TKlasse2.Create);
      2: list.Add(TKlasse3.Create);
      end;
    end;

    // ...

    for i := 0 to Pred(list.Count) do
      TKlasse1(list[i]).Free;                  // Hier sind beide Varianten möglich
      // (list[i] as TKlasse1).Free;

    MessageDlg('Fertig mit Free', mtInformation, [mbOk], 0);
  finally
    FreeAndNil(list);
  end;
end;

procedure TForm1.Button4Click(Sender: TObject);
var
   i: Integer;
  list: TObjectList;
begin
   list := nil;
  try
     list := TObjectList.Create;

    for i := 0 to Pred(MAX_OBJ) do begin
      case Random(3) of
      0: list.Add(TKlasse1.Create);
      1: list.Add(TKlasse2.Create);
      2: list.Add(TKlasse3.Create);
      end;
    end;

    // ...
  finally
    FreeAndNil(list);
  end;
end;

{ TKlasse1 }

constructor TKlasse1.Create;
begin
   inherited Create;
end;

destructor TKlasse1.Destroy;
begin
   MessageDlg('Destruktor Klasse 1', mtInformation, [mbOk], 0);
  inherited Destroy;
end;

{ TKlasse2 }

constructor TKlasse2.Create;
begin
   inherited Create;
end;

destructor TKlasse2.Destroy;
begin
   MessageDlg('Destruktor Klasse 2', mtInformation, [mbOk], 0);
  inherited Destroy;
end;

{ TKlasse3 }

constructor TKlasse3.Create;
begin
   inherited Create;
end;

destructor TKlasse3.Destroy;
begin
   MessageDlg('Destruktor Klasse 3', mtInformation, [mbOk], 0);
  inherited Destroy;
end;

end.

sirius 11. Sep 2008 09:24

Re: Free eines unbekannten Objektes
 
Zitat:

Zitat von olee
ja aber selbst als ich das hier verwendet habe:
Delphi-Quellcode:
  For i := 0 To Objects.Count - 1 Do
  begin
    T3DObj(Objects[i]).Free;
    Objects[i] := nil;
  end;
aber da fällt mir ein:

Man muss bedenken Objects[i] ist nicht WorldActor aber hat den gleichen wert

Du hast also zwei Referenzen auf ein Objekt. Wie gesagt, die Referenzen musst du per Hand auf nil testen. Aber du solltest eher etwas in deiner Logik verändern. Es geht prinzipiell nicht so wie du möchtest.

Sherlock 11. Sep 2008 09:26

Re: Free eines unbekannten Objektes
 
Vielleicht hab ich Deine Antwort überlesen, aber warum stellst Du nicht auf TObjectList um? Mit der Property OwnsObjects auf True gibt die automatisch alle angehängten Objekte selber frei sobald sie freigegeben wird.

Sherlock

olee 11. Sep 2008 13:37

Re: Free eines unbekannten Objektes
 
Ja das freigeben war ja nicht so richtig das Problem, wie sich herausgestellt hat.

Ich verwende jetzt eine TObjectList,

und das Problem habe ich so gelöst:

Delphi-Quellcode:
  If BEngine.Objects.IndexOf(WorldActor) >= 0 Then
    BEngine.Objects.Delete(BEngine.Objects.IndexOf(WorldActor));
Anstatt
Delphi-Quellcode:
If T3DObj(WorldActor) <> nil then T3DBlock(WorldActor).free;
Vielen dank für eure hilfe!
Und vor allem an Sirius, für die Hilfe bei meinem letzten Problem ^^

Das Ergebnis meiner Arbeit kann jetzt hier betrachtet werden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:48 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz