Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Objekte in eigener Liste ... Referenzproblem


IHops - Mo 24.11.08 10:17
Titel: Objekte in eigener Liste ... Referenzproblem
Hi, ich habe eine eigene Liste implementiert, diese sollte abstrakt mit beliebigen Objekten als Inhalt arbeiten können. Zur besseren Übersicht gebe ich mal das UML-Diagramm mit (Anhang).

Mein Problem liegt nun in der Übergabe eines Objekts aus dem Hauptprogramm heraus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TFrmMain.BtnAppendClick(Sender: TObject);
var
  C : TContent;
begin
  if Assigned(Liste) then
  begin
    if FrmDate.ShowModal = mrOK then
    begin
      C := TContent.Create;
      C.Name := FrmDate.EName.Text;
      C.Age := StrToInt(FrmDate.EAge.Text);
      Liste.Append(C);
      FreeAndNil(C);
    end;
  end
  else
    ShowMessage('Liste ist nicht vorhanden');
end;


In der Liste wird das dann wie folgt verarbeitet:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TListe.Append (Content: TContent);
var
  NewElement : TElement;
begin
  // Neues Element erzeugen
  NewElement := TElement.Create;
  NewElement.SetContent(Content);
  // Neues Element einbinden
  if IsEmpty then
    FRoot := NewElement;
  else
  begin
    while not IsLast do           // Letztes Element suchen
      FAktuell := FAktuell.GetNext;
    FAktuell.SetNext(NewElement);
  end;
  // Aktuelles Element neu setzen
  FAktuell := NewElement;
  FAktuell.SetNext(nil);
end;


Das Problem: Offensichtlich schieße ich mir mit FreeAndNil(C) nicht nur das Objekt in der Prozedur des Hauptprogramms, sondern auch das neu erzeugte Objekt der Liste ab. Das könnte daran liegen, dass ich nicht den Inhalt, sondern die Referenzadresse übergebe ... sind halt Zeiger auf Objekte. Nur, wie mache ich das richtig? Ich müsste den Inhalt übergeben, nicht die Referenz ...

Andere Frage dazu: In Delphi gibt es eine Klasse TList und eine Klasse TObjectList ... heißt das (auf meine Problem bezogen), ich kann mit einer "einfachen" Liste gar keine Objekte verwalten?


freedy - Mo 24.11.08 10:33
Titel: Re: Objekte in eigener Liste ... Referenzproblem
user profile iconIHops hat folgendes geschrieben Zum zitierten Posting springen:
Offensichtlich schieße ich mir mit FreeAndNil(C) nicht nur das Objekt in der Prozedur des Hauptprogramms, sondern auch das neu erzeugte Objekt der Liste ab.


Das ist richtig. Das Objekt wird damit freigeben. Die Freigabe darf erst erfolgen, wenn du deine Liste freigibst bzw. ein TElement aus der Liste löschst. Das FreeAndNil im Hauptprogramm kannst du dir sparen.
Um nun etwas konformer zu arbeiten (Ein Objekt wird da zerstört, wo es angelegt wird), solltest du aus dem Append eine Funktion machen, die dir einen leeren TContent zurückgibt. Den kannst du dann einfach befüllen.

Grüße


Delete - Mo 24.11.08 10:34

Der große Unterschied zwischen TList und TObjectList ist der, dass sich die TObjectList um die Speicherverwaltung der enthaltenen Objekte kümmert, sofern der Parameter OwnsObjects des Konstruktors auf true steht (default). Du solltest dies in Deiner eigenen Liste auch so handhaben. Außerdem wundere ich mich, dass Du ein Objekt erzeugst, Deiner Liste übergibst, dort noch einmal ein Objekt erzeugst und das Original dann freigibst. Welcher tiefere Sinn steckt denn dahinter?


platzwart - Mo 24.11.08 10:37

ehm... mit FreeAndNil zerstörst du das gerade erstellte objekt. lass das weg, dann sollte es auch funzen. das objekt soll ja in der liste weiter leben ;)


IHops - Mi 26.11.08 00:23

Also das mit dem FreeAndNil(C) ist richtig ... hätte ich auch selbst draufkommen können.

user profile iconfreedy hat folgendes geschrieben Zum zitierten Posting springen:
Um nun etwas konformer zu arbeiten (Ein Objekt wird da zerstört, wo es angelegt wird), solltest du aus dem Append eine Funktion machen, die dir einen leeren TContent zurückgibt. Den kannst du dann einfach befüllen.
Hm, das hört sich sinnvoll an, ich bekomms aber nicht ganz hin bzw. fange evtl. falsch an. Kannst du mir da etwas unter die Arme greifen?


freedy - Mi 26.11.08 10:10


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
  function TListe.Append : TContent;
  var
    NewElement : TElement;
    Content : TContent;
  begin
    // Neuen Content erzeugen
    Content := TContent.Create;
    Result := Content;    

    // Neues Element erzeugen
    NewElement := TElement.Create;
    NewElement.SetContent(Content); 


    ...

  end;