Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Alte Funktion ergänzen mit Overload


user32 - Di 29.03.16 21:36
Titel: Alte Funktion ergänzen mit Overload
Ich würde gerne die abs() Funktion erweitern, z.B für Vektoren.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function abs(Vect:TVec3):Double;overload;
begin
  result:=sqrt(Vect.X*Vect.X+
               Vect.Y*Vect.Y+
               Vect.Z*Vect.Z);
end;

Leider wird jetzt die Delphi-eigene Funktion anscheinend überschrieben.
Ich möchte diese aber nicht ersetzen, sondern nur zusätzlich eine Neue.
Wie geht das denn?


Narses - Di 29.03.16 21:57

Moin!

AFAIK gibt´s Überladung nur für Klassenmethoden, das ist aber eine Funktion aus einer Standard-Bibliothek. Kurz: so (wie von dir gewünscht) geht das gar nicht. :nixweiss:

cu
Narses


user32 - Di 29.03.16 22:22

Okay. Gibt's noch ne andere Möglichkeit? Außer jetzt meiner Funktion einen anderen Namen zu geben?^^
Ist jetzt auch keine Katastrophe wenn nicht, aber ich fände das schön wenn es ginge


Narses - Di 29.03.16 22:31

Moin!

user profile iconuser32 hat folgendes geschrieben Zum zitierten Posting springen:
Gibt's noch ne andere Möglichkeit?
Schreib den Unit-Namen davor, dann geht das auch. :nixweiss: Ob ich das empfehlen würde? Eher nicht... :?

cu
Narses


jaenicke - Di 29.03.16 22:39

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
AFAIK gibt´s Überladung nur für Klassenmethoden, das ist aber eine Funktion aus einer Standard-Bibliothek.
Das ist nicht richtig. Man kann auch einfache Funktionen und Prozeduren überladen.

Die Probleme sind hier andere:
Zunächst ist Abs keine Funktion, die direkt irgendwo in einer RTL-Unit definiert ist, sondern wird durch den Compiler per Compiler-Magic ergänzt. Deshalb kann sie auch verschiedene Typen als Parameter bekommen (siehe Syntaxergänzung).

Dazu kommt, dass die Originalfunktion auch mit Overload gekennzeichnet sein müsste um sie überladen zu können. Und sie kann nicht in einer anderen Unit stehen, wenn es sich nicht um eine Methode in einer Elternklasse, sondern eine einfache Funktion oder Prozedur handelt.

Du kannst die Funktion daher zwar definieren, aber nicht überladen. Die Originalfunktion ist über System.Abs nach wie vor erreichbar.

Deshalb stimmt user profile iconNarses Fazit:
Aus mehreren Gründen kann das direkt ohne irgendeinen Unitnamen vor der Funktion nicht funktionieren.


Narses - Di 29.03.16 22:49

Moin!

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
AFAIK gibt´s Überladung nur für Klassenmethoden, das ist aber eine Funktion aus einer Standard-Bibliothek.
Das ist nicht richtig. Man kann auch einfache Funktionen und Prozeduren überladen.
[...]
die Originalfunktion auch mit Overload gekennzeichnet sein müsste um sie überladen zu können.
Das meinte ich damit (man kriegt nachträglich das overload da nicht mehr reingebastelt), aber danke für die ausführliche Version. ;)

cu
Narses


jaenicke - Mi 30.03.16 04:08

Ah, ok, das habe ich dann falsch verstanden. Das las sich als ob du das generell meinst. :wink:

Wobei das ganze im Grunde eine Schwäche des Compilers ist. Denn logisch ließe sich das ja auflösen.


Martok - Mi 30.03.16 12:43

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Wobei das ganze im Grunde eine Schwäche des Compilers ist. Denn logisch ließe sich das ja auflösen.
Nur der Vollständigkeit halber: in FPC funktioniert das (auch im {$mode delphi}!), denn da ist auch Compilermagic normal (vorwärts-)deklariert und nur durch eine decoration weiß der Linker dann, dass er den Code dann da rein schubsen soll:

Delphi-Quelltext
1:
function abs(d : ValReal) : ValReal;[internproc:fpc_in_abs_real];                    



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function abs(c:char):char; overload;
begin
  Result:= upcase(c);
end;

var
  i: integer;
  c: char;
begin
  i:= abs(-1);
  c:= abs('a');
end.


Thom - Do 31.03.16 03:53


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
unit Vektoren;

interface

type
  Vector = record
    x, y, z: Double;
  end;

function Abs(X: Integer): Integer; overload;
function Abs(X: Int64): Int64; overload;
function Abs(X: Real): Real; overload;
function Abs(X: Vector): Double; overload;

implementation

function Abs(X: Integer): Integer;
begin
  Result:=System.Abs(X);
end;

function Abs(X: Int64): Int64;
begin
  Result:=System.Abs(X);
end;

function Abs(X: Real): Real;
begin
  Result:=System.Abs(X);
end;

function Abs(X: Vector): Double;
begin
  //...
end;

end.


Abs