![]() |
Delphi-Version: 10.3 Rio
Operator Overloading for CLASSES (not records!)
Hallo Community,
zunächst mal: ja, der Titel ist absichtlich in Englisch, damit ihn Leute auch finden, wenn sie in Google englische Begriffe eingeben. Zur Sache: Laut der aktuellsten Doku von Emba (Stand 23.01.2020) bzgl. der Überladung von Operatoren steht ganz klar im Text geschrieben, dass dieses Feature ausdrücklich auch für Klassen verwendbar wäre und nicht nur für Records: ![]() Ihr könnt es euch denken: der Konjunktiv steht da nicht umsonst. So, wie es dort beschrieben ist, geht es natürlich nicht - wäre auch zu schön gewesen, aber warum überrascht mich das nicht? :roll: Es hat mich schon stutzig gemacht, dass die Codebeispiele nur für Records geschrieben sind, aber man glaubt ja als naiver Entwickler zunächst mal das, was in der Doku geschrieben steht... Ein "Glück" - und deshalb formuliere ich ja diesen Beitrag auch - haben schlaue Leute eine Alternative gefunden. Diese wurde auch schon hier in den "Delphi-News aus aller Welt" verlinkt, allerdings ist dort der Link defekt. ( ![]() Daher habe ich hier mal den Link nochmal heraus gesucht: ![]() Jetzt sieht es aber so aus, dass diese Alternative nicht so ganz klappt, zumindest nicht für den Equal-Operator. Hat beim Thema "operator overloading" bei Klassen jemand Erfahrung, die mir/uns da weiterhelfen kann? |
AW: Operator Overloading for CLASSES (not records!)
Ich habe mich vor einiger Zeit
![]() |
AW: Operator Overloading for CLASSES (not records!)
Hallo,
Zitat:
|
AW: Operator Overloading for CLASSES (not records!)
Zitat:
Ich hab auch noch irgendwo beim Herumstöbern eine Erklärung gefunden, warum bisher kein operator overloading für Klassen implementiert wurde; hatte irgendwas mit dem Garbage Collector (GC) zu tun. Erklärt wurde das so, dass für jedes Mal, wo ein Operator ausgeführt wird, eine weitere Instanz der Klasse erzeugt werden müsste. Und die wird nur intern erzeugt, aber nicht freigegben und da es mit dem GC in Delphi ja nun etwas schwierig ist, würde diese Instanz als MemLeak weiter sein einsames Dasein fristen. So ganz steig ich da auch nicht durch. Aber das kann ich irgendwie nicht so recht glauben, dass man das mittlerweile nicht irgendwie gebacken bekommt. Ich sag's mal so: andere Programmiersprachen können's doch auch!? Und offenbar hat man das für iOS im Jahr 2013 schon umgesetzt, dann sollte man doch bis ins Jahr 2019 auch irgendwie für nicht-iOS-Systeme eine Lösung parat haben! Fehlender GC hin oder her... Und besonders lustig wird's dann, wenn in der Doku geschrieben steht, dass es gehen sollte. |
AW: Operator Overloading for CLASSES (not records!)
Zitat:
|
AW: Operator Overloading for CLASSES (not records!)
Zitat:
Mit ARC werden Objekte (TObject usw.) wie Interfaces behandelt, also automatisch freigegeben, wenn alle Variablen weg sind. (dafür wird Free einfach so still und heimlich ignoriert) Die ClassOperators benötigen aber eine automatische Speicherverwaltung, da der Entwickler (Du) das hier nicht selbst macht, bzw. oft garnicht machen kann. (Free aufrufen, wenn nicht mehr benötigt) Zitat:
Und dass der Compiler unbekannte Attribute nicht einfach so still und heimlich ignoriert. (da wenigstens eine Warnung anzeigt) Für Records wäre auch ein ClassOperator für New, Copy und Dispose praktisch, damit man dort z.B. auch Pointer und Objekte selbst behandeln kann, die im Record stecken. Hatte da vor vielen Jahren mal einen QC geschrieben, sogar mit Lösung was wo wie nötig wäre (wenige Codezeilen zu ändern), aber .... ich warte immernoch. Insgesamt macht ARC und NonARC hier echt Spaß, wenn man versucht einen objektorientierten Code zu schreiben, der auf allen Platformen funktioniert. Da kann man sich oft nur die Haare raufen und aufgeben. (außer man stellt alles komplett auf Interfaces um) |
AW: Operator Overloading for CLASSES (not records!)
Zitat:
Zitat:
|
AW: Operator Overloading for CLASSES (not records!)
Nee, das Erstellen machst du ja, in den Operatoren, und gibst es als Result zurück.
Drum ist dem Compiler das vollkommen egal. Zitat:
Klassen sind intern ein Record mit einem Pointer davor. (und der Pointer zeigt in die Mitte des Records, statt auf dessen Anfang) In Sowas wie Java, .NET und Dergleichen, da stimmt deine Aussage schon, wobei dort oft eher alles Objekte sind, soger ein schnöder Integer (drum kann der auch NULL bzw. EMPTY werden). |
AW: Operator Overloading for CLASSES (not records!)
Ich bin mir ziemlich sicher, dass der equals operator für Klassen auch auf ARC keine Beachtung findet, wenn left und right vom Typen sind, dem man diesen Operator verpasst.
Denn damit würde man den schon funktionierenden = Operator für TObject überschreiben können. Genauso kann man auch mit dem "&&op_*" Hack in einem helper einem Integer nicht seine = oder <, > Operatoren umschreiben. Es gibt übrigens 2 Arten von Operatoren: die, die neue "Instanzen" zurückgeben, wie z.B. Addition und solche die nur Boolean o.ä. zurückliefern wie Vergleiche - letztere wären auch ohne ARC komplett problemlos möglich. Zitat:
Zitat:
|
AW: Operator Overloading for CLASSES (not records!)
Zitat:
|
AW: Operator Overloading for CLASSES (not records!)
Wenn ich mal zusammenfassen darf: die Möglichkeit Operatoren zu überladen, ist wohl nur auf reinen ARC-Systemen möglich, sehe ich das jetzt richtig? Für nonArc-Systeme, also solche, bei denen man einen richtigen GC bräuchte oder aber selbst alle Objekte wieder frei gibt, ist das nicht realisierbar?
|
AW: Operator Overloading for CLASSES (not records!)
Zitat:
|
AW: Operator Overloading for CLASSES (not records!)
Klassen sind keine Records, und Records sind keine Klassen. Nur weil eine Klasse Felder wie ein Record hat und somit ein Teil ihres Speicherlayouts dem eines Records gleicht, macht es das nicht zum Record oder könnte gar dessen Funktionalitäten übernehmen - auch wenn intern für einige Dinge vom Compiler generierte record type Info genutzt wird (um zum Beispiel Felder für managed types korrekt zu finalisieren).
Klassen sind Referenztypen (Zeiger auf idR heapallokierten Speicher) und Records sind Wertetypen. Ja, man kann Zeiger auf Records haben und sie auch selbst aufm Heap allokieren, aber dann hantiert man nunmal mit Zeigern, also einem Referenztyp auf einen Wertetypen. Records und die Operatoren, welche einen Record zurück geben arbeiten idR mit CopyRecord und der Standardmechanismus für Methoden, die einen Record zurückliefern, finden statt - Keine Heapallokation. Ein Operator, der Objekte zurückgeben würde, müsste eine Heapallokation durchführen. Generell noch kein Problem, aber wenn man zum Beispiel den Code
Delphi-Quellcode:
hat, wird dort mind ein Temp Wert erzeugt (entweder a+b oder b+c) und erst das ergebnis dieses Temp Wertes mit dem dritten Wert landet in x, bei einer Heapallokation -> Speicherleck.
x := a + b + c;
|
AW: Operator Overloading for CLASSES (not records!)
Zitat:
|
AW: Operator Overloading for CLASSES (not records!)
Zitat:
Was mich an der Sache hier viel mehr interessiert hat waren überladene Operatoren in Record Helpers. Das wäre wirklich eine nützliche Sache. Denn damit könnte man das Standardverhalten für einfache Typen lokal übersteuern. Beispiel:
Delphi-Quellcode:
das wäre doch viel übersichtlicher als komplexe if-or-or-or-then-Konstrukte. Noch besser wäre natürlich, wenn case auch mit Strings umgehen könnte:
var
S: string; begin S := 'foo'; if S in ['foo', 'bar'] then begin {...} end; end;
Delphi-Quellcode:
Für case-Anweisungen fehlt irgendwie ein überladbarer Operator. Equality spielt da zwar mit rein, aber case an sich ist nicht flexibel genug. Da ist switch-case in anderen Sprachen (z.B. Javascript, PHP) deutlich komfortabler.
var
S: string; begin S := 'foo'; case S of 'foo': {...} 'bar': {...} end; end; |
AW: Operator Overloading for CLASSES (not records!)
Ich bin froh, dass das nicht geht. Das verhindert damit oft unsauberen Code. (Wegen SoC
![]() |
AW: Operator Overloading for CLASSES (not records!)
Zitat:
|
AW: Operator Overloading for CLASSES (not records!)
Zitat:
Zitat:
![]() ![]() Bzgl Verbesserung des case of Statements: einfach mal nen Vote für ![]() |
AW: Operator Overloading for CLASSES (not records!)
Zitat:
|
AW: Operator Overloading for CLASSES (not records!)
Nativ fehlt halt so Einiges in Delphi, was man schonmal gebraucht hätte. (Einiges gibt es zum Glück von Fremdanbietern, was aber auch schnell den Gesamtpreis von Delphi etwas in die Höhe treibt)
DefaultPropery für Strings (das mit dem Default-Attritut ist schon blöd, denn Eines steht davor und das Andere dahinter und wenn ich jetzt frage wer von euch überhaupt weiß dass es sowas gibt, dann hebt bestimmt kaum jemand die Hand), Attribute hinter dem was man beschreiben will (statt davor/drüber), kleine Makros, assoziative Arrays, ein besseres CASE, ... Nicht schön, aber was soll's.
Delphi-Quellcode:
case IndexStr(S, ['A', 'B', 'C']) of
0{A}: ...; 1{B}: ...; 2{C}: ...; end; type TX = (A, B, C); //case TX(IndexStr(S, ['A', 'B', 'C'])) of case TX(GetEnumValue(TypeInfo(TX), S)) of A: ...; B: ...; C: ...; end; |
AW: Operator Overloading for CLASSES (not records!)
Zitat:
|
AW: Operator Overloading for CLASSES (not records!)
Zitat:
|
AW: Operator Overloading for CLASSES (not records!)
:hi:
und danke für die Erinnerung das es sowas gibt ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:21 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