![]() |
Delphi-Version: 2006
Suboptimale Klassenoperatoren?
Weiß eigentlich jemand, warum man einige Operatoren echt bescheuert implementiert hat?
Inc, Dec, Include und Exclude müssten ja eigentlich als Var-Parameter existieren und nicht mit einem nutzlosen Result-Parameter? Im Ergebnis verliert man dadurch doch gerade den Vorteil dieser Funktionen Prozeduren, welche eigentlich direkt die Variable verändern und nicht erst eine Kopie erstellen und damit das Original überschreiben. :wall: Das jetzt noch zu ändern wäre wohl zu spät. :? |
AW: Suboptimale Klassenoperatoren?
Zitat:
|
AW: Suboptimale Klassenoperatoren?
Zitat:
wenn sie var-Parameter hätten, dann würde ja das Original überschrieben werden als Function mit Rückgabewert bleibt ja das Original unberührt |
AW: Suboptimale Klassenoperatoren?
Wisst ihr (ausgenommen Uwe, der weiß es) eigentlich, was das mit dem
Delphi-Quellcode:
auf sich hat?
class operator
Delphi-Quellcode:
Preisfrage: Welchen Wert hat jetzt
type
TFoo = record Value: Integer; class operator Inc( a: TFoo ): TFoo; end; { TFoo } class operator TFoo.Inc( a: TFoo ): TFoo; begin Result.Value := a.Value + 1; end; procedure Test; var LFoo : TFoo; begin LFoo.Value := 1; Inc( LFoo ); end;
Delphi-Quellcode:
?
LFoo.Value
|
AW: Suboptimale Klassenoperatoren?
Zitat:
Sei i: Integer, dann produziert "Inc(i)" Code, der den Inhalt von i an Ort und Stelle ("In-Place") erhöht. In Rufos Beispiel produziert "Inc( LFoo )" dagegen Code, der TFoo.Inc(LFoo) aufruft, was eine temporäre Kopie von LFoo erstellt, die erhöht, nur um das Ergebnis dann gleich wieder LFoo zuzuweisen. Also praktisch: "LFooTemp := LFoo.Inc; LFoo := LFooTemp;" Dieser zusätzliche Schritt mit der Kopie erscheint unnötig und kann mit größeren Records Leistung verschwenden. |
AW: Suboptimale Klassenoperatoren?
Ja und? Ein Record kann ja nun auch etwas umfangreicher als ein
Delphi-Quellcode:
sein und auch das
Integer
Delphi-Quellcode:
kann dann durchaus etwas anspruchsvoller sein als einfach nur einen Wert hochzuzählen.
Inc
Und da man eben nicht weiß (und es eben komplexer sein kann) ist es genau so umgesetzt worden. |
AW: Suboptimale Klassenoperatoren?
Der springende Punkt ist, dass Inc und Dec für Standardtypen In-Place-Operationen sind und deshalb auch für Class Operators sein sollten.
Das wäre konsistenter und schneller. Wenn ich "komplexeres" Verhalten und eine Kopie möchte, kann ich auch einfach TFoo + 1 benutzen. Wenn der Delphi-Compiler besser optimieren würde, dann wäre das kein Ding. Leider tut er es aber nicht... |
AW: Suboptimale Klassenoperatoren?
Da die es nicht wussten, sollte es "normal" implementiert sein, also als VAR.
Wenn der Typ das nicht unterstützt, dann kann man es "intern" immernoch anders umsetzen.
Delphi-Quellcode:
Genau genommen fehlt sogar noch die Inc-Version mit zwei Parametern. :wall:
class operator TMyRecord.Inc(var Value: TMyRecord);
var Temp: TMyRecord; begin Temp := Value; ... Value := ...; end;
Delphi-Quellcode:
Inc(i, 123);
Zitat:
Aus technischen Gründen ist es "anfangs" nur für Records implementiert wurden. Warum man vergessen hat das für Interfaces zu bauen, weiß ich nicht. (das ginge schon immer) Dankt ARC wäre es, inzwischen seit XE4, auch möglich das bei Objekten (Klassen) zu benutzen. :zwinker: Und grade bei Objekten wird der das immer mehr, wenn nun auch noch Objektinstanzen erstellt und freigegeben werden müssen, statt nur einem billigem Record. Ein Vorteil bei den Objekten ist, daß man dort tricksen kann und bei diesen Operatoren einfach die selbe Objektreferenz zurückgibt. (wenn man blind hofft, daß Emba diese Funktionen nicht doch mal für zwei Objekte benutzt) |
AW: Suboptimale Klassenoperatoren?
So kann man sich täuschen.
Ich dachte immer, dass ein
Delphi-Quellcode:
intern so funktioniert, dass der Wert von
var
Value: Integer; Inc( Value );
Delphi-Quellcode:
ausgelesen, dann um 1 erhöht (ergibt einen neuen Wert, der auch Speicher belegt) und dann zurückgeschrieben wird.
Value
Delphi-Quellcode:
oder noch etwas anders geschrieben
procedure Inc( var AValue : Integer );
begin AValue := AValue + 1; end;
Delphi-Quellcode:
Also ganz genau wie das hier bei den Records passiert, da ein Record eben auch nur einen komplexerer Wert darstellt.
function IntegerInc( AValue : Integer ): Integer;
begin Result := AValue + 1; end; procedure Inc( var AValue : Integer ); begin AValue := IntegerInc( AValue ); end; |
AW: Suboptimale Klassenoperatoren?
Das Ding ist, dass der Compiler bei nem Integer schlau genug ist, auch einfach nen inc daraus zu generieren ohne temporäre Resultvariable. Das ist bei operator overloading leider nicht der Fall - Stichwort
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:11 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