AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

Ein Thema von Andreas13 · begonnen am 29. Feb 2016 · letzter Beitrag vom 1. Mär 2016
Antwort Antwort
Seite 1 von 2  1 2   
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
719 Beiträge
 
Delphi XE5 Professional
 
#1

Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

  Alt 29. Feb 2016, 15:55
Delphi-Version: XE5
Hallo Delphi-Community,

ich möchte die „mitgelieferte“ Sortierroutine QuickSort der Klasse TArray in System.Generics.Collections durch eine verbesserte QuickSort-Routine ersetzen.

Hierzu habe ich eine Klasse von TArray wie folgt abgeleitet:
Delphi-Quellcode:
unit Test_TArray_QuickSort;

{$R-,T-,X+,H+,B-}  // genauso, wie in unit System.Generics.Collections

interface

uses
   System.Generics.Collections
, System.Generics.Defaults
;

type
  MyTArray = class(TArray)
  private
    class procedure QuickSort<T>(var Values: array of T; const Comparer: IComparer<T>;
      L, R: Integer);
  end;

implementation

class procedure MyTArray.QuickSort<T>(var Values: array of T; const Comparer: IComparer<T>;
  L, R: Integer);
Begin
 // hier neue QuickSort-Routine
End;

Für Testzwecke habe ich in der beiliegenden Unit anstelle der „neuen Routine“ zunächst Delphi XE5’s Originalversion unverändert übernommen.

Im folgenden Konsolen-Programm wollte ich die neue Klasse austesten:

program Sortieren_0;

{$APPTYPE CONSOLE}

{$R *.res}


uses
  System.SysUtils
, System.Generics.Collections
, Test_TArray_QuickSort in 'Test_TArray_QuickSort.pas';

VAR
  S : String;
  Arr : TArray<String>;
  MyArr: MyTArray<String>; // hier rebelliert der XE5-Compiler! Warum?????????

Begin
  Try
   // Code nach: Rolliston, Ch.: Delphi XE2 Foundations: (2012) Seite 288:
   Arr:= TArray.Create<String>('things', 'SOME', 'some', 'THINGS');
   TArray.Sort<String>(Arr);
   For S in Arr Do Write(S, ' ');
   WriteLn;


   MyArr:= MyTArray.Create<String>('things', 'SOME', 'some', 'THINGS');
   MyTArray.Sort<String>(MyArr);
   For S in MyArr Do Write(S, ' ');
   WriteLn;

   ReadLn;

  Except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  End;
End.
Hierzu verwendete ich einen kleinen 4-Zeiler aus dem Buch: Rolliston, Ch.: Delphi XE2 Foundations: (2012) Seite 288.

Der Test funktioniert einwandfrei mit dem Objekt der Original-Klasse TArray, das Programm lässt sich jedoch bei der absolut identischen Vorgehensweise mit der Instanz der abgeleiteten Klasse MyTArray NICHT einmal compilieren. Anscheinend gilt doch die lateinische Weisheit „Quod licet Iovi, non licet bovi“. Ich bin kurz vor dem Verzweifeln…

Im Anhang sind beide komplette Files dabei:

Program Sortieren_0.dpr und unit Test_TArray_QuickSort.pas

dabei.

Könnte mir jemand von den Object-Profis freundlicherweise helfen?

Vielen Dank im Voraus!

Gruß

Andreas
Angehängte Dateien
Dateityp: dpr Sortieren_0.dpr (814 Bytes, 1x aufgerufen)
Dateityp: pas Test_TArray_QuickSort.pas (1,4 KB, 3x aufgerufen)

Geändert von Phoenix ( 1. Mär 2016 um 12:52 Uhr) Grund: Delphi-Tags eingefügt. Das nächste mal bitte selber machen.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.474 Beiträge
 
Delphi 12 Athens
 
#2

AW: Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

  Alt 29. Feb 2016, 17:09
TArray ist etwas völlig anderes als TArray<T> . Schau dir mal die beiden Deklarationen an und überleg mal, warum du keine Variable vom Typ MyTArray<T> brauchst.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
719 Beiträge
 
Delphi XE5 Professional
 
#3

AW: Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

  Alt 29. Feb 2016, 17:35
Sorry Uwe, aber ich komme als "Object-Anfänger" leider nicht dahinter.
Könntest Du mir bitte den Unterschied zwischen TArray und TArray<T> erklären? Ich dachte <T> signalisiert dem Compiler, dass der übergebene Typ "vererbt" wird.
Danke!

Andreas
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.024 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#4

AW: Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

  Alt 29. Feb 2016, 17:36
Dein Ansatz wird nicht funktionieren. Denn TArray.Sort wird immernoch TArray.QuickSort aufrufen und nicht plötzlich MyTArray.QuickSort.
Vorrausgesetzt du willst diese Funktionalität auch in TList<T>.Sort und so verwenden, wird das auch nicht hinhauen,
denn du bekommst dort ohne Änderung der RTL Sourcen keinen andere Implementierung untergeschoben.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.474 Beiträge
 
Delphi 12 Athens
 
#5

AW: Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

  Alt 29. Feb 2016, 17:59
Könntest Du mir bitte den Unterschied zwischen TArray und TArray<T> erklären?
Delphi-Quellcode:
TArray<T> = array of T

TArray = class
TArray ist eine Hilfsklasse, die eine Reihe generischer Methoden zur Verfügung stellt. Insbesondere speichert TArray keine Daten irgendwelchen Typs.

Wie Stevie schon sagte, ist dein ganzes Bemühen sinnlos, da QuickSort nicht virtuell ist und somit nicht überschrieben werden kann. Du kannst allenfalls eine Kopie von TArray nehmen und dort deine Implementierung von QuickSort unterbringen. Das hat aber auf die interne Implementation und deren Verwendung keinen Einfluss.

Vielleicht erklärst du mal, was du eigentlich erreichen willst?
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
719 Beiträge
 
Delphi XE5 Professional
 
#6

AW: Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

  Alt 29. Feb 2016, 19:28
danke Uwe und Stefan für die Aufklärung und die Erklärung des Unterschiedes zwischen den beiden Typen.

Mein ursprüngliches Ziel war es, anstelle meiner x typ-spezifischen Sortierroutinen EINE einzige Routine zu verwenden, die ALLE Array-Typen "schluckt". Dazu hat mich TArray.QuickSort<T> inspiriert. Als ersten Schritt wollte ich dazu als "schnelle" Lösung ein abgeleitetes Objekt a la oben aufgeführten Quellcode benutzen. Denn auch ich habe bemerkt, dass TArray.QuickSort<T> intern auf eine ziemlich komplexe Weise mit aller Welt verknüpft ist. Als zweiten Schritt wollte ich schließlich ein eigenes typ-unabhängiges Objekt erstellen...

Lässt sich mit objektorientiertem Ansatz eine solche Routine - ohne Pointer-Akrobatik - programmieren, die ALLE Array-Inhalte verarbeiten kann? Bisher habe ich - prozedural - meistens mit "overload" gearbeitet.

Gruß, Andreas

Geändert von Andreas13 (29. Feb 2016 um 19:30 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.474 Beiträge
 
Delphi 12 Athens
 
#7

AW: Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

  Alt 29. Feb 2016, 19:40
TArray.Sort<T> arbeitet doch schon mit Arrays beliebigen Typs.

Delphi-Quellcode:
var
  intarr: TArray<Integer>;
  strArr: TArray<string>;
begin
  TArray.Sort<Integer>(intArr);
  TArray.Sort<string>(strArr);
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.173 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

  Alt 29. Feb 2016, 20:00
Wenn du beispielsweise ein Array von Records oder sonstwas sortieren willst kannst du bei TArray.Sort auch einen IComparer<T> angeben. Siehe Doku

Sieht dann, etwas länglich, so aus:

Delphi-Quellcode:
program Project11;

{$APPTYPE CONSOLE}

{$R *.res}

uses System.Generics.Collections, System.Generics.Defaults;

type
   TMyRecord = record
      alsWort:   String;
      alsZahl:   Integer;
   end;

var
   a, b, c:   TMyRecord;
   comparer:   IComparer<TMyRecord>;
   meinArray:   TArray<TMyRecord>;
begin
   a.alsWort := 'Dreiundzwanzsch'; a.alsZahl := 23;
   b.alsWort := 'Nüscht'; b.alsZahl := 0;
   c.alsWort := 'Sievenunfünfzsch'; c.alsZahl := 57;

   comparer := TComparer<TMyRecord>.Construct(
      function(const left, right: TMyRecord): Integer
      begin
         Result := TComparer<Integer>.Default.Compare(left.alsZahl, right.alsZahl);
      end
   );

   SetLength(meinArray, 3); meinArray[0] := a; meinArray[1] := b; meinArray[2] := c;
   // Ab XE7 ginge stattdessen auch das hier:
   //meinArray := [a, b, c];

   TArray.Sort<TMyRecord>(meinArray, comparer);

   WriteLn(meinArray[0].alsWort);
   WriteLn(meinArray[1].alsWort);
   WriteLn(meinArray[2].alsWort);
   ReadLn;
end.
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
719 Beiträge
 
Delphi XE5 Professional
 
#9

AW: Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

  Alt 29. Feb 2016, 23:08
Hallo zusammen,

danke für die vielen nützlichen Tipps, Hinweise und Anregungen: ich habe dabei von EUCH eine ganze Menge gelernt und Vieles ist mir klar geworden!

Mit diesem soeben erworbenen Know-how konnte ich sogar meine ursprüngliche Routine realisieren und TArray.QuickSort(. . .) in den ABGELEITETEN Klassen auf „meine“ Sortierroutine umbiegen.

Hier ist das Ergebnis, falls sich jemand dafür interessieren sollte:

Delphi-Quellcode:
unit Test_TArray_QuickSort;

interface

uses
   System.Generics.Collections
, System.Generics.Defaults
;

type
  MyTArray = class(TArray)
  private
    class procedure QuickSort<T>(var Values: array of T; const Comparer: IComparer<T>;
      L, R: Integer);
  public
    class procedure Sort<T>(var Values: array of T); // !!
  end;

implementation

class procedure MyTArray.QuickSort<T>(var Values: array of T; const Comparer: IComparer<T>;
  L, R: Integer);
Begin
// hier soll die neue QuickSort-Routine folgen:
End;

class procedure MyTArray.Sort<T>(var Values: array of T);
begin
  QuickSort<T>(Values, TComparer<T>.Default, Low(Values), High(Values));
end;

Und das Testprogramm:
program Sortieren_0_verbessert;

{$APPTYPE CONSOLE}

{$R *.res}


uses
  System.SysUtils
, System.Generics.Collections
, Test_TArray_QuickSort in 'Test_TArray_QuickSort.pas';

VAR
  S : String;
  MyArr: TArray<String>; // !!!


Begin
   MyArr:= TArray<String>.Create('things', 'SOME', 'some', 'THINGS');
   SetLength(MyArr, 5);
   MyArr[4]:='Irgend etwas';
   MyTArray.Sort<String>(MyArr);

   For S in MyArr Do Write(S, ' ');
   WriteLn;

   ReadLn;
End.
Herzlichen Dank an Euch Alle!

Gruß, Andreas

Geändert von Phoenix ( 1. Mär 2016 um 12:51 Uhr) Grund: Delphi-Tags eingefügt. Das nächste mal bitte selber machen.
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.640 Beiträge
 
#10

AW: Ersetzen der privaten class procedure QuickSort<T> (. . .) der Klasse TArray

  Alt 1. Mär 2016, 12:53
Andreas, bitte achte in Zukunft darauf in Deinen Posts den Quellcode mit [delphi]-tags zu umschliessen, damit dieser auch richtig formatiert wird.
Das habe ich jetzt gemacht, weil es Beschwerden von Usern gab die das schlecht lesen konnten, aber für die Zukunft bitte selber daran denken, ja?
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:55 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