Einzelnen Beitrag anzeigen

automatix

Registriert seit: 1. Mai 2008
Ort: Remscheid
39 Beiträge
 
Delphi 2007 Enterprise
 
#15

Re: Free eines unbekannten Objektes

  Alt 11. Sep 2008, 08:19
Hallo!

Dies funktioniert, wie schon geschrieben, nicht.

  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.
  Mit Zitat antworten Zitat