| Autor |
Beitrag |
Marco D.
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: Mi 03.01.07 21:18
Gibt es eine Möglichkeit, eine Klasse, die mit einem bestimmten Datentyp arbeitet, z.B. integer, so abzuändern, dass sie ohne große Änderungen auch mit anderen Datentypen umgehen kann? In C++ nennt sich so etwas Template.
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Mi 03.01.07 21:25
Hallo!
Das geht meines Wissens in Delphi noch nicht. Mir ist auch kein Workaround bekannt, mit dem man das machen kann.
Das nächste Delphi soll Generics (die das ermöglichen) unter .NET und (IIRC) auch unter Win32 unterstützen.
Grüße
Christian
P.S.: Bevor der Einwand kommt: Ja, ich weiß, Generics und Templates weisen grundsätzliche Unterschiede auf, aber die Anwendungen sind sehr ähnlich 
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
Marco D. 
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: Mi 03.01.07 21:29
Also muss ich mehrere Units entwerfen, die alle der gleichen Klasse zugrunde liegen?
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Mi 03.01.07 22:10
Christian S. hat folgendes geschrieben: | | Mir ist auch kein Workaround bekannt, mit dem man das machen kann. |
Bevor's jemand anders postet: www.dummzeuch.de/del...mplates/deutsch.html
Aber: Don't. Use. This.
Das sind keine Templates.
| Christian S. hat folgendes geschrieben: | Ja, ich weiß, Generics und Templates weisen grundsätzliche Unterschiede auf, aber die Anwendungen sind sehr ähnlich  |
Fragt sich nur, ob in der nativen Version von Delphi die Generics genauso implementiert werden, wie unter .NET, oder doch eher C++-artig. Ich würde eher auf letzteres tippen 
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 03.01.07 22:32
Für viele Zwecke kann man auch Variants benutzen. Das ist zwar etwas völlig anderes als Templates, aber wenn du Prozeduren mit denselben Operationen für verschiedene Typen verwenden willst, dann geht das damit.
Aber Variants gibts ja auch in C++, insofern brauche ich dazu vielleicht auch nicht viel zu sagen.
Diese Vorgehensweise hat allerdings viele Nachteile, unter anderem ist die Geschwindigkeit nicht gut. Nichtsdestotrotz verwende ich die manchmal.
Ein kleines Beispiel:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| function Sum(a, b: Variant): Variant; begin Result := a + b; end;
begin ShowMessage(Sum(3, 4)); ShowMessage(Sum('aaa', 'bbb')); |
Nochmal ganz deutlich: Ich behaupte nicht, dass das etwas wie Templates ist, ich sage nur, dass man es teilweise anstatt Funktionstemplates verwenden kann, weil man eine Funktion (eingeschränkt) mit verschiedenen Datentypen genauso verwenden kann.
Ich denke aber, dass die beste Lösung, vor allem bei möglichst schnellen Routinen, die in einer Schleife aufgerufen werden, immer noch das Kopieren ist...
Und mit Klassen geht das sowieso nicht mit Variants.
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Do 04.01.07 02:24
Marco D. hat folgendes geschrieben: | | Gibt es eine Möglichkeit, eine Klasse, die mit einem bestimmten Datentyp arbeitet, z.B. integer, so abzuändern, dass sie ohne große Änderungen auch mit anderen Datentypen umgehen kann? In C++ nennt sich so etwas Template. |
Hallo,
es geht nicht wirklich, aber ich verwende für Ini-Einträge eine Art Brute-Force-Lösung für das Problem:
Meine Klasse TRKiniSettingValue kann bool, integer, real, ShortString und noch ein paar andere Typen wie Color aufnehmen, dazu verfügt sie über Speichermöglichkeiten (getrennt) für alles und über Construktoren wie Create_Bool (), Create_Integer usw. Diese Konstruktoren legen also den Typ fest. Viele der Methoden müssen natürlich zur Laufzeit mit Case prüfen, welcher Typ aktuell gespeichert ist. Zugriff erfolgt mit spezialisierten Routinen wie Get_Bool, Put_Bool, damit ist sogar eine strenge Typprüfung gewährleistet.
Es sieht so aus, als wäre damit nicht nicht viel gewonnen, aber die Vorteile zeigen sich bei der weiteren Verwendung: alle Ini-Einträge haben die gleiche Klasse, und in einer Verwaltungsklasse wie TRKiniSettingTable können sie alle zusammen verwaltet werden, z.B. kann eine Routine ReadAllIniSettings einfach über die Einträge iterieren - jeder Eintrag liest sich dann quasi selbst aus der Ini-Datei.
Das ganze hat eher Ähnlichkeit mit virtuellen Methoden anstatt mit Templates, löst aber einige Probleme.
Gruss Reinhard
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Do 04.01.07 13:41
Reinhard Kern hat folgendes geschrieben: | | [eigenwilliger Interpretation von Templates] |
Um einen neuen Typ hinzuzufügen, musst du aber einen neuen Konstruktor einführen und an dutzenden Stellen im Code weitere case-Zweige einführen, um diesen Typ zu behandeln. Genau das ist es ja, was man normalerweise nicht will, wenn man nach Templates schreit
| Reinhard Kern hat folgendes geschrieben: | | Es sieht so aus, als wäre damit nicht nicht viel gewonnen, aber die Vorteile zeigen sich bei der weiteren Verwendung: alle Ini-Einträge haben die gleiche Klasse, und in einer Verwaltungsklasse wie TRKiniSettingTable können sie alle zusammen verwaltet werden, z.B. kann eine Routine ReadAllIniSettings einfach über die Einträge iterieren - jeder Eintrag liest sich dann quasi selbst aus der Ini-Datei. |
Klingt so, als hätte man Konstruktoren, die sich an Namenskonventionen halten, wenn man virtuelle Methoden benutzen würde. Welche Probleme löst denn den Vorgehen?
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Do 04.01.07 17:33
tommie-lie hat folgendes geschrieben: | Reinhard Kern hat folgendes geschrieben: | | [eigenwilliger Interpretation von Templates] | Um einen neuen Typ hinzuzufügen, musst du aber einen neuen Konstruktor einführen und an dutzenden Stellen im Code weitere case-Zweige einführen, um diesen Typ zu behandeln. Genau das ist es ja, was man normalerweise nicht will, wenn man nach Templates schreit
...
|
So ist es - klar bleibt die Klasse intern komplex, aber nach aussen wird die Komplexität verborgen und die Objekte können einheitlich bearbeitet werden. Ausserdem werden z.B. Abschnitts- und Variablen-Namen im Konstruktor definiert, ebenso ein ev. zugehöriges TControl wie TEdit, mit dem der User den Wert setzen kann - alles übersichtlich an einer Stelle, eben dem Konstruktor, und v.a. nur einmal im Projekt. Diese Kostruktoren werden ihrerseits im Konstruktor der Settings-Tabelle nacheinander aufgerufen - das ist die zentrale Anlaufstelle für Änderungen im Projekt für alles, was mit Settings zu tun hat.
Templates machen sich ja auch nicht von allein, natürlich muss ich für einen neuen Typ nicht nur das Template selbst schreiben, sondern auch die Methoden dafür. Der Nachteil bei mir besteht nur darin, dass in bereits getesteten Code eingegriffen wird. Der Arbeitsaufwand ist auch nicht höher als bei Templates, wie dort auch unterscheiden sich die Konstruktoren ja nur geringfügig.
Ich will aber niemand dazu überreden, irgendetwas aus dieser Software zu verwenden, sie wurde ausschliesslich zur internen Verwaltung der Settings in meinen Projekten geschrieben und da hat sie sich gut bewährt, auch wenn das alles möglicherweise theoretisch Mist ist.
Gruss Reinhard
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Do 04.01.07 17:52
Reinhard Kern hat folgendes geschrieben: | | Templates machen sich ja auch nicht von allein, natürlich muss ich für einen neuen Typ nicht nur das Template selbst schreiben, sondern auch die Methoden dafür. |
Ja nee, wenn sich die Objekte nicht selbst serialisieren können und ich solche Verrenkungen brauche, müsste ich auch für Templates Spezialisierungen implementieren, für alles, was über Basistypen hinausgeht (die können sich nämlich selbst serialisieren bzw werden von dne Streams serialisiert).
Aber du schrobst | Reinhard Kern hat folgendes geschrieben: | | Das ganze hat eher Ähnlichkeit mit virtuellen Methoden anstatt mit Templates, löst aber einige Probleme. |
Welche Probleme löst es denn, die man mit virtuellen Methoden hätte? Du hast in deinem letzten Post eben selbst nur Nachteile gegenüber virtuellen Methoden aufgezählt, nämlich Eingriff in funktionierenden Code und eine komplexe Klassenimplementierung. Ich meine, du wirst sicherlich einen Grund dafür haben, es so zu machen, wie du es machst.
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
GTA-Place
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: Do 04.01.07 18:30
_________________ "Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Do 04.01.07 18:35
GTA-Place hat folgendes geschrieben: | | Eine Alternative hierzu wären natürlich auch überladene Prozeduren / Funktionen. |
Ja nee, das will man ja normalerweise gerade nicht, lässt sich aber bei dem von dir genannten Beispiel gar nicht anders machen.
Der OP sprach von einem Template und ich glaube er weiß, was er wollte.
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
GTA-Place
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: Do 04.01.07 18:41
Das bezog sich auch nicht auf den OP sondern auf den Variant-Vorschlag von jaenicke. Und selbst bei den Standardfunktionen wird sowas häufiger vewendet, z.B. min() oder max() aus der Unit Math für verschiedene Datentypen. Und wenn man auf verschiedene Datentypen, verschieden reagieren will - z.B. den Bindestrich in meinem Beispiel - dann ist das eine der wenigen [oder die einzigste] Möglichkeite[n].
Lenkt aber vom Thema ab, also B2T.
_________________ "Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Do 04.01.07 19:06
tommie-lie hat folgendes geschrieben: |
...
Aber du schrobst | Reinhard Kern hat folgendes geschrieben: | | Das ganze hat eher Ähnlichkeit mit virtuellen Methoden anstatt mit Templates, löst aber einige Probleme. | Welche Probleme löst es denn, die man mit virtuellen Methoden hätte? Du hast in deinem letzten Post eben selbst nur Nachteile gegenüber virtuellen Methoden aufgezählt, nämlich Eingriff in funktionierenden Code und eine komplexe Klassenimplementierung. Ich meine, du wirst sicherlich einen Grund dafür haben, es so zu machen, wie du es machst. |
Hallo Tommie,
dazu habe ich jetzt eine dreiviertel Seite geschrieben, aber die hat mir die DF-Software geraubt: zu lang geschrieben, Neuanmeldung erforderlich, Text weg. Und zum Wiedereintippen fehlt mir jetzt die Zeit.
Ist sicher kein Bug sondern ein Feature, erschliesst sich mir aber im Moment noch nicht ganz.
Gruss Reinhard
|
|
|