![]() |
Arbeiten mit TList
Hallo,
ich möchte eine verkettete Liste von Punkttypen erstellen. Da ich nicht das Rad neu erfinden will, hab ich mit TList angeschaut und versucht , davon meine Liste abzuleiten. Ich bin mir aber nicht sicher, ob das nun von der Logik her so richtig ist. Was haltet Ihr davon:
Delphi-Quellcode:
Unit listen;
Interface Uses Classes, Typendef; Type PunktType = Record X : real; Y : real; lage : byte; End; pPunktType = ^PunktType; { TPunktTypeList class } TPunktTypeList = Class(TList) Private Protected Procedure Notify(Ptr : Pointer;Action : TListNotification); Override; Function GetPkt(inIndex : Integer) : PunktType; Procedure SetPkt(inIndex : Integer;inPkt : Punkttype); Public Constructor Create; Function Add(inPkt : Punkttype) : Integer; Function Remove(inIndex : Integer) : Integer; Property Items[inIndex : Integer] : Punkttype Read GetPkt Write SetPkt;Default; End; { TPunktTypeList class } Implementation { TPunktTypeList } Function TPunktTypeList.Add(inPkt : Punkttype) : Integer; Var p : pPunkttype; Begin New(p); Result:=Inherited Add(p); End; Constructor TPunktTypeList.Create; Begin Inherited Create; End; Function TPunktTypeList.GetPkt(inIndex : Integer) : PunktType; Begin Result:=pPunkttype(Inherited Items[inIndex])^; End; Procedure TPunktTypeList.Notify(Ptr : Pointer;Action : TListNotification); Begin If Action = lnDeleted Then Dispose(pPunkttype(Ptr)); Inherited Notify(Ptr, Action); End; Function TPunktTypeList.Remove(inIndex : Integer) : Integer; Begin Result:=Inherited Remove(Inherited Items[inIndex]); End; Procedure TPunktTypeList.SetPkt(inIndex : Integer;inPkt : Punkttype); Begin pPunkttype(Inherited Items[inIndex])^:=inPkt; End; End. |
Re: Arbeiten mit TList
Wäre es nicht einfacher, aus dem Record eine Klasse zu machen und die Liste dann von TObjectlist abzuleiten?
|
Re: Arbeiten mit TList
Das wäre mir lieber, aber der Punkttype ist der grundlegende Typ in unserem Programm. Da wird das Ersetzen eines Records durch eine Klasse doch ungemein schwierig.
|
Re: Arbeiten mit TList
Na gut, wenn es nicht anders geht. Allerdings fällt mir auf, dass die Parameter und Rückgabewerte vom Typ PunktType sind, aber eigentlich vom Typ pPunktType sein müssten.
|
Re: Arbeiten mit TList
Nö, soweit geht das schon, aber
Delphi-Quellcode:
ist nicht so gut, da dein inPkt gar nicht in die Liste aufgenommen wird, sonder ein leerer Punkt.
Function TPunktTypeList.Add(inPkt : Punkttype) : Integer;
Var p : pPunkttype; Begin New(p); Result:=Inherited Add(p); End;
Delphi-Quellcode:
Gruss
Function TPunktTypeList.Add(inPkt : Punkttype) : Integer;
Var p : pPunkttype; Begin New(p); p^ := inPkt; // <=== fehlt hier Result:=Inherited Add(p); End; [Edit:thkerkmann]Korrektur Zugweisung [/Edit] |
Re: Arbeiten mit TList
Stimmt. :wall: Ja es ist wieder Zeit sich über sich selbst aufzuregen. Danke!
|
Re: Arbeiten mit TList
du weisst aber schon, dass TList ein Array ist und keine liste ... :roll:
|
Re: Arbeiten mit TList
Ja, soweit ich weiß ist eine TList ein Array von Zeigern. Aber es bietet mir die Funktionen einer verketteten Liste und eine bessere Speicherverwaltung als ein dynamisches Array.
|
Re: Arbeiten mit TList
kommt drauf an was du machen willst, willst nur ein paar daten im speicher hin und herschieben, so ist ein array sicher recht gut. nachteilig wird das ganze, wenn du viele daten umordnen willst, bei der verketteten liste musst du nur ein paar pointer umhängen, bei einem array (z.b. tList) den ganzen speicher umschichten.
aber sonst, ist natürlich die TList bequemer ... :-) , ist aber natürlich keine (verkettete) liste ... Zitat:
|
Re: Arbeiten mit TList
Zitat:
Gerd |
Re: Arbeiten mit TList
Zitat:
|
Re: Arbeiten mit TList
Zitat:
Zitat:
|
Re: Arbeiten mit TList
Zitat:
|
Re: Arbeiten mit TList
Zitat:
|
Re: Arbeiten mit TList
Zitat:
|
Re: Arbeiten mit TList
Meine Intention hierbei war einfach, dass bei Add nur einmal neuer Speicher für den neuen Punkt angefordert wird. Beim Arbeiten mit dynamischen Arrays kann es meines Wissens nach oft sein, dass das komplette Array im Speicher verschoben wird. Wenn ich einige hundert Punkte habe und beim hinzufügen immer ein setlength mache, finde ich das nicht ganz optimal.
Gut das gleiche hätte auch eine verkette Liste getan, aber die hätte ich komplett implementieren müssen... So nun hab ich mir auch mal ein wenig Quelltext von TList angesehen. @littleDave TPointerList ist so definiert:
Delphi-Quellcode:
Also wird gleich für die maximale Länge der Liste Speicher für die Pointer reserviert und dieser auch nicht zur Laufzeit verändert.
MaxListSize = Maxint div 16;
TPointerList = array[0..MaxListSize - 1] of Pointer; Beim Löschen werden nicht alle folgenden Elemente zurückgeschoben, sondern nur der letzte gültige Pointer an die leere Stelle kopiert. |
Re: Arbeiten mit TList
Zitat:
Gerd |
Re: Arbeiten mit TList
TPointerList ist nur ein Dummy-Typ. In TList wird ja einfach PPointerList verwendet. Der Compiler weiß dann, dass der Speicher, auf den der Pointer zeigt, ein array ist. Somit kann man direkt PPointerList[i] aufrufen und der Compiler macht das restliche. Man könnte TPointerList auch definieren als array[0..0] of pointer. Es wird das gleiche rauskommen. Der Typ ist nur dafür da, damit man die eckigen Klammern benutzen kann.
Zitat:
Zitat:
Delphi-Quellcode:
procedure TList.Delete(Index: Integer);
begin { ... } if Index < FCount then // Mit dem Move-Befehl werden alle Pointer, die nach index kommen, // um eine Position (4 Byte bei 32Bit-Systemen) nach vorne geschoben System.Move(FList^[Index + 1], FList^[Index], (FCount - Index) * SizeOf(Pointer)); { ... } end; |
Re: Arbeiten mit TList
Stimmt auch wieder ...
Nun ja, auf jeden Fall hab ich bei diesem Thread einiges gelernt! :-D Danke dafür!!! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:25 Uhr. |
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-2025 by Thomas Breitkreuz