![]() |
Generics.TObjectList Items vertauschen
Ich möchte übungshalber eigene Sortierroutinen schreiben und Generics üben.
Nun habe ich versucht, Quicksort (kopiert von classes.pas) zum Laufen zu bringen, aber offensichtlich (?) darf man nicht zwei Elemente mit Items[i] := Items[j] vertauschen -- zumindest erhalte ich sofort einen EInvalidPointer ("ungültige Zeigeroperation) mit Absturz, wenn ich es ausführe. Wie vertauscht man denn zwei Items miteinander? Was mache ich falsch? (PS: Im Vergleich zu meiner zweiten Frage bzgl. URW1111 ist hier alles identisch, nur in EINER Unit zusammengezogen.)
Code:
unit MainForm;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Generics.Collections; type TSortObjectList<T: class> = class(TObjectList<T>) type TCompareItems<T> = function(AItem, BItem: T): Integer of Object; procedure QuickSort(Left, Right: Integer; ACompareMethod: TCompareItems<T>); overload; end; TMyItem = class(TObject) Dummy: String; end; TTestList = class(TSortObjectList<TMyItem>) end; TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; { enthält sieben Zeilen mit jeweils einem Buchstaben } procedure Button1Click(Sender: TObject); private function CompareTest(AItem, BItem: TMyItem): Integer; end; var Form1: TForm1; implementation {$R *.dfm} procedure TSortObjectList<T>.QuickSort(Left, Right: Integer; ACompareMethod: TCompareItems<T>); var I, J: Integer; Pivot, Temp: T; begin { QuickSort procedure from Classes.pas. } repeat I := Left; J := Right; Pivot := Items[(Left + Right) shr 1]; repeat while ACompareMethod(Items[I], Pivot) < 0 do Inc(I); while ACompareMethod(Items[J], Pivot) > 0 do Dec(J); if I <= J then begin Temp := Items[I]; Items[I] := Items[J]; Items[J] := Temp; Inc(I); Dec(J); end; until I > J; if Left < J then QuickSort(Left, J, ACompareMethod); Left := I; until I >= Right; end; procedure TForm1.Button1Click(Sender: TObject); var A : TTestList; j : Integer; function MakeTestItem(AString: String): TMyItem; begin Result := TMyItem.Create; Result.Dummy := AString; end; begin A := TTestList.Create(True); for j := 0 to Pred(Memo1.Lines.Count) do A.Add(MakeTestItem(Memo1.Lines[j])); A.QuickSort(0, Pred(A.Count), CompareTest); Memo1.Clear; for j := 0 to Pred(A.Count) do Memo1.Lines.Add(A[j].Dummy); A.Free; end; function TForm1.CompareTest(AItem, BItem: TMyItem): Integer; begin Result := CompareStr(AItem.Dummy, BItem.Dummy); end; end. |
AW: Generics.TObjectList Items vertauschen
Ah ja, ich habe selbst die Funktion Exchange() entdeckt, frage mich aber rein interessehaber dennoch, warum man nicht dierekt die Items einander zuweisen kann. Was ist falsch mit diesem Vorgehen?
|
AW: Generics.TObjectList Items vertauschen
Das liegt an dem OwnsObjects der TObjectList, sobald das true ist und du die Items so zuweist, wird das bestehende Item freigegeben. Die Delphi interne Implementierung in System.Generics.Collections.pas TArray<T>.QuickSort arbeitet direkt mit dem Array of T von der TObjectList und nicht mit der TObjectList selber.
|
AW: Generics.TObjectList Items vertauschen
Super Antwort, verständlich und logisch. Danke!
Exchange() hat das Problem zum Glück inhaltlich gelöst, aber nun ist auch klar, warum es nicht ging. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:44 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