Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Komplexe TList kopieren (https://www.delphipraxis.net/158014-komplexe-tlist-kopieren.html)

Rakshasa 2. Feb 2011 12:00

Komplexe TList kopieren
 
Hallo Leute,

für meine Undo-Funktion erstelle ich Kopien meiner aktuellen TList-Sturktur. Die TList besteht aus Record-Pointern, die wiederum selbst mehrere TLists enthalten, Strings, Integer, andere records.

Momentan gehe ich die einzelnen Elemente der TList durch und erstellt manuell einen neuen Pointer, welchen ich dann der neuen TList zuweise. Dieses Verfahren ist aber sehr mühselig; gibt es eine Möglichkeit, den gesamten Speicher, der den Pointer einer TList enthält zu kopieren und diese Kopie dann einer neuen TList zuzuweisen?

WM_CLOSE 2. Feb 2011 15:01

AW: Komplexe TList kopieren
 
Bei reinen Werttypen (z.B. Integer) ist das kein großes Prob,
aber sobald man zu Strings stößt, fangen die Probleme an.
Ganz zu schleigen von anderen Objekten wie TLists in dem Record.
Die Variable vom Typ TList speichert ja nur einen Pointer.
Den kannst du kopieren wie du willst, der zeigt immernoch auf dasselbe TList Objekt.
Mit den Strings verhält es sich ähnlich.

Ich hab das mal so getestet:

Delphi-Quellcode:
procedure Test
type
  TMyRecord=record
    str:array[0..5]of char;
    int:Integer;
  end;
  pMyRecord=^tMyRecord;
var
  List1:TList;
  List2:TList;
  i:TMyRecord;
  p:pMyRecord;
begin
  List1:=TList.Create;
  List2:=TList.Create;
  try
    i.int:=0;
    i.str:='Hase';
    ShowMessage(i.str);
    List1.Add(@i);
    ShowMessage(TMyRecord(List1[0]^).str);
    new(p);
    try
      List2.Add(p);
      TMyRecord(List1[0]^):=TMyRecord(List2[0]^);
      Inc(TMyRecord(List2[0]^).int);
      ShowMessage(IntToStr(TMyRecord(List1[0]^).int));
      ShowMessage(IntToStr(TMyRecord(List2[0]^).int));
      TMyRecord(List2[0]^).str:='Ratte';
      ShowMessage(TMyRecord(List1[0]^).str);
      ShowMessage(TMyRecord(List2[0]^).str);
    finally
      dispose(List2[0]);
    end;
  finally
    list1.Free;
    list2.Free;
  end;
end;
Komischerweise hat es sogar ein mal funktioniert. Das Problem bei dem Beispiel dürfte die Referenzzählung des Strings sein.

ChrisE 2. Feb 2011 15:06

AW: Komplexe TList kopieren
 
Hallo,

keine Ahnung ob es tut, aber was ist mit Delphi-Referenz durchsuchenTList.Assign?

Gruß, Chris

WM_CLOSE 2. Feb 2011 15:17

AW: Komplexe TList kopieren
 
TList.Assign kopiert nur die Pointer (=Elemente in der Liste) hab es grad getestet.

webcss 2. Feb 2011 15:22

AW: Komplexe TList kopieren
 
Wie wär's mit Tobject anstatt record,

Dann geschwind ein Basis Object mit einer Clone methode gestrickt und eine ebensolche in eine eigene TList Klasse

und mit MyRootList.Clone ist der Lack fertig?

himitsu 2. Feb 2011 16:12

AW: Komplexe TList kopieren
 
die "ordentliche" Methode:

- statt der Records+Pointer ebenfalls Objekte verwenden
- allen enthaltenen Objekten eine "Clone"-Funktion verpassen
- TList auf eine erweiterte TObjectList ändern, welche diese Clone-Funktion verwendet.

> die Liste übergibt nun in Assign ihren Inhalt an die andere Liste
> dabei wird über .Clone eine Kopie des enthaltenen Objektes erstellt und in die neue Liste eingefügt
> jedes Objekt kopiert in .Clone auch untergeordnete Objekte, welche wiederrum über .Clone kopiert und ins neue Objekt eingetragen werden
> usw.

Also wie schon erwähnt.
Ich weiß aber nicht, ob Delphi 2007 schon TObject.Clone kennt ... wenn doch, dann dieses überschreiben und wenn nicht, dann selber eines einführen.

Rakshasa 2. Feb 2011 21:54

AW: Komplexe TList kopieren
 
Hmm...mit TObject habe ich mich noch nicht beschäftigt, eine .Clone-Function kennt mein Delphi 2007 nicht. Ich werde mal schauen, was ich hier so finden kann; ansonsten wirds wohl erstmal bei manuellen Kopieren bleiben..

Danke!

Bummi 2. Feb 2011 22:07

AW: Komplexe TList kopieren
 
Die Clone-Funktion müsstest Du den Klassen selbst beibringen...
Wenn Du Deine Kopierroutinen im Griff und optimiert hast und diese für Wartbar hältst besteht eh kein Handlungsbedarf. Schneller wird es durch genannte Methoden nicht, nur wartbarer.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:08 Uhr.

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