Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Rueckgabewerte von ueberladenen Funktionen? (https://www.delphipraxis.net/44079-rueckgabewerte-von-ueberladenen-funktionen.html)

alcaeus 13. Apr 2005 08:27


Rueckgabewerte von ueberladenen Funktionen?
 
Hallo allerseits,

im anderen Thread habe ich ja ein Optionssystem angesprochen. Um die Optionswerte zu holen, wollte ich eigentlich Methoden verwenden, die auch schon den entsprechenden Typecast (von String) vornehmen. Allerdings scheint das mit den ueberladenen Methoden nicht zu funktionieren:

Delphi-Quellcode:
function GetOption(iOptionConst: Integer): String; overload;
function GetOption(iOptionConst: Integer): Integer; overload;
In der zweiten Zeile schimpft der Compiler: "Declaration of GetOption differs from previous declaration". Dass sich die Deklarationen sich unterscheiden ist mir klar, aber sollte das nicht der Sinn und Zweck von ueberladenen Funktionen sein? :gruebel:
Oder muessen sich etwa die Parameterlisten unterscheiden? Wenn ja, wie sollte ich das sonst machen? Die Optionswerte werden als String abgespeichert und es waere natuerlich geschickt wenn ich eine Funktion habe, die mir direkt den gewuenschten Wert auf den richtigen Typ castet und zurueckgibt.
Kann mir jemand helfen?

Thanx and Greetz
alcaeus

jim_raynor 13. Apr 2005 08:32

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Ja, bei Überladenene Funktionen müssen sich die Parameter unterscheiden, denn sonst weiß der Compiler nicht welche Funktion genutzt werde soll. Entweder nutzt du Variants (was natürlich wesentlich langsamer ist) oder du musst einfach die Funktionen unterschiedlich benennen, so wie es bei verschiedenen Inkarnationen von TRegistry und ähnlichem der Fall ist.

alcaeus 13. Apr 2005 09:09

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Na gut, dann werde ich wohl mit solchen "Aushilfsmethoden" arbeiten (muessen).

Greetz
alcaeus

SubData 13. Apr 2005 09:16

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Ich verwende dafür nen Variant, das geht auch wunderbar :)
Delphi-Quellcode:
function Config(Section, Value: String; Default: Variant; Typ: String = 'V'): Variant; Overload;
var
  Read : Variant;
  ReadInt : Integer;
begin
  // Einen Konfigurationswert zurückgeben...
  if (Typ <> 'R') then Read := CfgValues.Values[Section + '_' + Value];
  if (Typ = 'R') then
  begin
    Read := CfgRegExp.Values[Section + '_' + Value];
    if not (Read <> '') then Read := Default;
    if not (Read <> '') then Read := '$';
    Result := Read;
  end;
  if ((Typ = 'V') or (Typ = 'S')) then
  begin
    if not (Read <> '') then Read := Default;
    Result := Read;
  end;
  if (Typ = 'B') then
  begin
    Result := Default;
    if (Read = '1') then Result := True;
    if (Read = '0') then Result := False;
  end;
  if (Typ = 'I') then
  begin
    if not (TryStrToInt(Read, ReadInt)) then Result := Default
    else Result := ReadInt;
  end;
end;

Edit: Es gibt die Funktion nochmal deswegen der Overload...

Delphi-Quellcode:
function Config(Section, Value: String; Typ: String = 'V'): Variant; Overload;
begin
  Result := Config(Section, Value, '', Typ);
end;

alcaeus 13. Apr 2005 09:32

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Zitat:

Zitat von SubData
Ich verwende dafür nen Variant, das geht auch wunderbar :)

Ja, allerdings moechte ich die Verwendung von Variants soweit wie moeglich vermeiden, weil Fehler nicht ganz so ersichtlich sind. Ich behalte deine Loesung aber mal im Hinterkopf.

Greetz
alcaeus

SubData 13. Apr 2005 09:35

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Aus dem Grund kannste ja den Typ angeben der zurück gegeben werden soll :mrgreen:

Aber hast schon Recht, ich versuche auch weitgehend auf Variants zu verzichten :>

DevilsCamp 19. Jul 2005 08:20

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Da ich gerade das selbe Problem habe habe ich diesen Thread gefunden


Zitat:

Zitat von jim_raynor
Ja, bei Überladenene Funktionen müssen sich die Parameter unterscheiden, denn sonst weiß der Compiler nicht welche Funktion genutzt werde soll. Entweder nutzt du Variants (was natürlich wesentlich langsamer ist) oder du musst einfach die Funktionen unterschiedlich benennen, so wie es bei verschiedenen Inkarnationen von TRegistry und ähnlichem der Fall ist.

Ich habe folgenden Code:

Delphi-Quellcode:
interface
  function Test(Bla: String): String; overload;
  function Test(Bla: String): Integer; overload;

implementation

function Test(Bla: String): String;
begin
  Result := 'Hallo '+Bla;
end;

function Test(Bla: String): Integer;
begin
  Result := StrToIntDef(Bla, 0);
end;

procedure Hallo;
var
  i : Integer;
  s : String;
begin
  s := Test('Peter');
  i := Test('12345');
end;

end.
Der Compiler weiß doch, dass s ein String und i ein Integer ist. Wieso ist er also nicht in der Lage herauszufinden, dass s die Funktion benötigt, die ein String zurückgibt und i die entsprechende Integer-Variante?

Das das bei Prozeduren mit selben Parametern nicht funktionieren kann ist klar, aber bei Funktionen ist diese Einschränkung doch etwas unlogisch.

Ich verweise da mal auf die nette Funktion Explode aus der Code-Library. Die gibt dort ein String-Array zurück. Genauso gut kann man die aber auch so umschreiben, dass ein Integer-Array zurück gegeben wird. Und das bei der selben Parameter-Liste.

Und genau das ist z.Z. mein Problem. :)
Dass ich die Funktion wohl nicht beliebig nutzen kann, nur weil der Compiler es nicht mag, wenn nur der Ergebnis-Typ unterschieldich ist :( :( :(

mirage228 19. Jul 2005 08:26

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Hi,

Diese Entscheidung kann der Compiler nicht (immer) treffen.

Was sollte er denn in diesem Fall tun:

Delphi-Quellcode:
var
  V: Variant;
begin
  V := Test('Peter');
end;
Soll er nun einen Integer oder String zurückgeben?

Es wäre zu zeitaufwendig für den Compiler immer herauszufinden, in welchem Kontext die Funktion benutzt wird. Bei Parametern ist es da einfacher.

mfG
mirage228

leddl 19. Jul 2005 08:44

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Außerdem könnte man theoretisch die Funktion auch ohne Zuweisung aufrufen.

Robert_G 19. Jul 2005 09:14

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Zitat:

Zitat von leddl
Außerdem könnte man theoretisch die Funktion auch ohne Zuweisung aufrufen.

Richtig!
Genau deshalb gehört der Rückgabewert nicht zur Signatur einer Funktion. (Ein Prozedur ist ja auch nur ein Funktion, die nüscht zurückgibt ;) )
Da für Overloads die Signatur eindeutig sein muss, sollte klar sein warum das nicht geht. ;)

DevilsCamp 19. Jul 2005 09:18

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Delphi-Quellcode:
function Test(Bla: String): String; overload;
function Test(Bla: String): Integer; overload;

procedure Hallo;
var
  s : String;
  i : Integer;
begin
  s := Test('Hallo');
  i := Test('12345');

  Test('Servus');   // <---- hier sollte der Compiler dann meckern und sonst nicht ;)
end;
Könnten wir uns auf obigen QuellCode einigen? ;)

leddl 19. Jul 2005 09:21

Re: Rueckgabewerte von ueberladenen Funktionen?
 
:gruebel: Klar könnten wir uns einigen, nur der Compiler wird trotzdem schon vorher meckern :lol:

DevilsCamp 19. Jul 2005 09:27

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Leider.

Wird mir wohl wirklich nichts anderes übrig bleiben als den Funktionsnamen zu ändern :cry: :cry:

barf00s 19. Jul 2005 09:35

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Falls ihr dennoch auf Variants setzt, dann verwendet auch die Funktionen aus der Variants.pas, mit denen man den Inhalt dieser Variablen prüfen - oder deren internen Typ abfragen, was zur Fehlerbehandlung beitragen sollte. </sülz>

Ansonsten sollte man Variants allerdings vermeiden - aus besagten Gründen ;)

DevilsCamp 19. Jul 2005 14:06

Re: Rueckgabewerte von ueberladenen Funktionen?
 
oder ich benutze statt einer Funktion eine Prozedur und übergebe die Variable, in der das Ergebnis stehen soll als var-Parameter :D :D :D


Delphi-Quellcode:
procedure Test(Bla: String; var Result: String); overload;
procedure Test(Bla: String; var Result: Integer); overload;

BlackJack 19. Jul 2005 14:50

Re: Rueckgabewerte von ueberladenen Funktionen?
 
@DevilsCamp: wundert mich dass diese Methode nicht schon viel eher vorgeschlagen würde, die kam mir beim lesen des threads als aller erstes in den sinn :D

barf00s 19. Jul 2005 15:18

Re: Rueckgabewerte von ueberladenen Funktionen?
 
prozeduren sind ohnehin 800% schneller als funktionen, in der verarbeitung

SubData 19. Jul 2005 15:21

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Zitat:

Zitat von barf00s
prozeduren sind ohnehin 800% schneller als funktionen, in der verarbeitung

Kannst du diese Aussage bitte begründen?

(Ich will dich damit nicht anprangern, sondern es interessiert mich wirklich, warum das so ist / sein soll)

Dax 19. Jul 2005 15:42

Re: Rueckgabewerte von ueberladenen Funktionen?
 
@barf00s: Warum erzählst du solchen Unsinn? :gruebel:

Kuck dir das mal an:

Delphi-Quellcode:
program Project5;

uses
  Windows;

{$APPTYPE CONSOLE}

function TestF(I: Integer): Integer;
begin
  Result := I + 1;
end;

procedure TestP(I: Integer; var Result: Integer);
begin
  Result := I + 1;
end;

var
  Dump, I: Integer;
  _Begin, _End, _Dif: Int64;

begin
  Dump := 0;
  QueryPerformanceCounter(_Begin);
  for i := 0 to 10000000 do
    Dump := TestF(Dump);
  QueryPerformanceCounter(_End);
  _Dif := _End - _Begin;
  WriteLn('Functiontest : ', _Dif, ' Ticks');
  Dump := 0;
  QueryPerformanceCounter(_Begin);
  for i := 0 to 10000000 do
    TestP(Dump, Dump);
  QueryPerformanceCounter(_End);
  _Dif := _End - _Begin;
  WriteLn('Proceduretest: ', _Dif, ' Ticks');
  Readln;
end.
Und das Ergebnis, das dabei rauskommmt:

Zitat:

Functiontest : 165575 Ticks
Proceduretest: 326003 Ticks
Ich würde doch mal sehr behaupten, Prozeduren seien langsamer ;)

Edit: Copy&Waste :oops:

DevilsCamp 19. Jul 2005 15:55

Re: Rueckgabewerte von ueberladenen Funktionen?
 
was hast du für einen Rechner?


Bei mir kommt folgendes raus:
Code:
Functiontest        Proceduretest
      471782                383582
      481778                406912
      473677                384258
      487796                381966
      488406                384659
      480697                402065
      479277                384486
      481221                377313
      475937                377417
      475279                402056

Bei mir sind die Procedures schneller

TeronG 19. Jul 2005 16:07

Re: Rueckgabewerte von ueberladenen Funktionen?
 
1. Ich will nen neuen Firmenrechner :( (viel zu lahm)
2. bei mir sind Functionen schneller (s.u.)
3. sorry für OT :pale:

Code:
Functiontest : 85139024 Ticks
Proceduretest: 108814560 Ticks
EDIT:
AHA !!! zuvor war MIT IDE
und das ist ohne:
Code:
Functiontest : 157207020 Ticks
Proceduretest: 129074536 Ticks

Functiontest : 92841112 Ticks
Proceduretest: 104016952 Ticks

Functiontest : 104332344 Ticks
Proceduretest: 101967576 Ticks
schwankt ziemlich ....

DGL-luke 19. Jul 2005 16:08

Re: Rueckgabewerte von ueberladenen Funktionen?
 
aber nach 800mal sieht es nicht gerade aus...

ich meine, eine prozedur ist doch auch nur ein call bzw. jmp/jr.

wenn man nun wüsste, in welchen maschinencode das var (klar, eine variable wird gesetzt) bzw. das reult:= / return umgesetzt wird, könnte man daraus natürlich rückschlüsse ziehen.

aber ist das nicht ein wenig off topic?

Dax 19. Jul 2005 16:09

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Ich hab nen P4 1,8GHz, falls das was zur Sache tut ;) Aber anscheinend ist der Zeitunterschied Prozedur - Funktion Prozessorabhängig.

Zitat:

Zitat von DGL-luke
wenn man nun wüsste, in welchen maschinencode das var (klar, eine variable wird gesetzt) bzw. das reult:= / return umgesetzt wird, könnte man daraus natürlich rückschlüsse ziehen.

Für Funktionen erzeugt ein Result := ... ein

Code:
MOV EAX, ...
Im Beispielcode erzeugt der Compiler nur ein

Code:
ADD EAX, 1
Bei Prozeduren siehts anders aus, in diesem Fall käme

Code:
ADD EAX, 1
MOV [EDX], EAX
und als Standard zum Result-setzen

Code:
MOV addresse/[register], ...

DerDan 19. Jul 2005 16:18

Re: Rueckgabewerte von ueberladenen Funktionen?
 
QueryPerformanceCounter ist halt auch schon Prozessorabhängig!

DerDan

BlackJack 19. Jul 2005 18:47

Re: Rueckgabewerte von ueberladenen Funktionen?
 
Zitat:

Zitat von DGL-luke
aber nach 800mal sieht es nicht gerade aus...

800% <> 800 mal so schnell ;D

barf00s 20. Jul 2005 08:02

Re: Rueckgabewerte von ueberladenen Funktionen?
 
hört auf zu streiten -

Funktionen haben einen Rückgabewert - und in Rückgabewerte werden die Ergebnise reinkopiert, dafür gehen Rechenzyklen drauf -
wenn mein c++ e weng besser wär würdichs euch mit dem Post/Prefix dings wie bei ++i/i++ erklärn - wo auch ++i schneller is wie jeder weis

[edit]
es sollte vllt noch gesagt werden das prozeduren nicht _immer_ schneller sind, bei bestimmten mathematischen konstellationen können auch funktionen gleichschnell oder gar _schneller_ sein

blah -
nehmt die sache nicht so ernst - soooooo zeitkritische programme schreibt ihr eh nicht.
[/edit]

brechi 20. Jul 2005 08:13

Re: Rueckgabewerte von ueberladenen Funktionen?
 
@barf00s

da muss ich dir aber wiedersprechen :)

bei Funktionen wird der rückgabewert ins register EAX geschrieben
bei Prozeduren mit VAR Parametern wird das an eine Speicherstelle geschrieben (was vorher schon erwähnt wurde) demnach sind Prozeduren langsamer WENN das zuweisen oft vorgenommen wird, d.h. oft in den VAR parameter geschrieben wird.


aber nen wirklichen merkbaren unterschied gibt es wirklich nicht.
kommt auch drauf anwie der compiler das optimiert, kann ja sein das der bei ner prozedur auch immer alles erst in eax schreibt udn am ende in die variable dann ist das gleich schnell

barf00s 20. Jul 2005 08:15

Re: Rueckgabewerte von ueberladenen Funktionen?
 
ich wiedersprech dir ja auch nicht - hab ja nicht gesagt das procs _immer_ schneller sind als _funcs_

beispiel wäre da matrizenrechnerreien oder son blödsinn -

naja auch egal ;)
wir wissen wies gemeint war


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:20 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