Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Rückgabewert von Funktionen / evtl. Problem mit try..finally (https://www.delphipraxis.net/35090-rueckgabewert-von-funktionen-evtl-problem-mit-try-finally.html)

changlee 2. Dez 2004 13:34


Rückgabewert von Funktionen / evtl. Problem mit try..finally
 
Hallo,
ich habe ein grundsätzliches Verständnisproblem was den Rückgabewert einer Funktion angeht.
Bevor ich viel drum herum rede hier einfach zwei code-Beispiele:

Delphi-Quellcode:
function meineFkt(str: String): TMeinTyp;
var x : TMeinTyp;
begin
  x:=TMeinTyp.Create;
  try
    x.property1:='Hallo 1';
    x.property2:='Hallo 2';
    result:=x;
  finally
    x.free;
  end;
end;
Bei der Obenstehenden Funktion wird kein Wert zurückgegeben (bzw. wird ein Leerstring zurückgegeben).

Schreibe ich hingegen..
Delphi-Quellcode:
function meineFkt(str: String): TMeinTyp;
var x : TMeinTyp;
begin
  x:=TMeinTyp.Create;
  x.property1:='Hallo 1';
  x.property2:='Hallo 2';
  result:=x;
end;
..funktioniert alles so wie es sollte. Damit könnte man sich eigentlich zufrieden geben.
Aber ich würde gern dazu zwei Dinge wissen:
1. wann funktioniert result? Nur am Ende einer Funktion / außerhalb von Schleifen?
2. Wenn ich x.free nicht aufrufe, hat das irgendwelche Nachteile, oder wird x sowieso nach Funktionsende wieder freigegeben, da es sich um eine lokale Variable handelt?

An try..finally kann es widerum eigendlich nicht liegen, denn wenn ich folgendes schreibe klappt es auch nicht:
Delphi-Quellcode:
function meineFkt(str: String): TMeinTyp;
var x : TMeinTyp;
begin
  x:=TMeinTyp.Create;
  x.property1:='Hallo 1';
  x.property2:='Hallo 2';
  result:=x;
  x.free;
end;
Kann mir diesbezüglich jemand weiterhelfen?
Das wär wirklich sehr nett!

mfg
changlee

Luckie 2. Dez 2004 13:38

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Es wird dir nichts zurückgegeben, weil du das Objekt und somit den Speicherbereich wieder freigibst.
Delphi-Quellcode:
result := x;
Beinhaltet nur die Kopie eines Zeigers. Gibst du mit
Delphi-Quellcode:
x.Free;
das Objekt frei und machst so den Zeiger ungültig, ist auch die Kopie leer.

Ich würde so was imme rmit var Parametern lösen, dann weiß man dass der Aufrufer dafür verantwortlich ist, denm Speicher auch wieder aufzuräumen. L´äßt du nämlich das Free weg, hast du Speicherleichen.

Jasocul 2. Dez 2004 13:41

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
result ist vom Typ deines Rückgabe-Typs.
Früher gabs result gar nicht. Da musste man das Ergebnis dem Funktionsnamen zuweisen. Da es aber manchmal notwendig ist, mit Zwischenergebnissen des Funktionsergebnisses innerhalb der Funktion weiter zu arbeiten, wurde von Borland Result eingeführt. Ansonsten gibt es rekursive Funktionsaufrufe.

Das bedeutet in deinem Fall, solange du die Werte deiner Variablen nicht der Funktion oder result zuweist, weiß die Funktion auch nicht welchen Wert sie zurückliefern soll.
Deine temporäre Variable benötigst du also gar nicht, da du Result dafür verwenden kannst.

jim_raynor 2. Dez 2004 13:41

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Es wird der Wert zurückgegeben der zuletzt in result gespeichert.

Da Objekte als Zeiger übergeben werden, wird auch nur der Zeiger zurückgegeben und wie Luckie schon sagte, zerstörst du das Objekt bevor du die Funktion beendest. Deshalb bekommst du nichts sinnvolles zurück.

[edit]Willkommen bei der Delphi-PRAXIS. :party: [/edit]

Luckie 2. Dez 2004 13:43

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Zitat:

Zitat von Jasocul
Deine temporäre Variable benötigst du also gar nicht, da du Result dafür verwenden kannst.

Macht aber Sinn, da der Kompiler so noch das eax Register zur Verfügung hat und so besser optimieren kann. Aber das ist nicht sein Problem.

changlee 2. Dez 2004 13:53

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Hallo,
vielen Dank für die schnellen aussagekräftigen Antworten!
Ich werde es jetzt wohl mit var-Parametern lösen.
mfg
changlee

Jasocul 2. Dez 2004 14:11

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Zitat:

Zitat von changlee
Hallo,
vielen Dank für die schnellen aussagekräftigen Antworten!
Ich werde es jetzt wohl mit var-Parametern lösen.

Warum? :gruebel:

Luckie 2. Dez 2004 14:17

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
OK, das Schlüsselwort var dürfte zwar überflüssig sein. Macht aber deutlich was passiert.

changlee 2. Dez 2004 14:18

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Hi,
warum nicht? (Lucky hatte es doch auch so vorgeschlagen).
mfg
changlee

Luckie 2. Dez 2004 14:29

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Ich bin nicht unfehlbar und es mag noch andere Möglichkeiten geben ohne dass ein Speicherleck zurück bleibt. Nur mir var Parametern scheint es mir am einfachsten und sichersten zu sein.

Jasocul 2. Dez 2004 14:30

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Ich hätte mein "Warum" klarer formulieren sollen. Aber Luckie hats ja schon beantwortet.

MaBuSE 2. Dez 2004 14:34

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Zitat:

Zitat von changlee
Ich werde es jetzt wohl mit var-Parametern lösen.

Ich würde es so machen:
Delphi-Quellcode:
function meineFkt(str: String): TMeinTyp;
begin
  Result := TMeinTyp.Create;
  Result.Property1 := 'Hallo 1';
  Result.Property2 := 'Hallo 2';
end;
bzw bei vielen Properties:
Delphi-Quellcode:
function meineFkt(str: String): TMeinTyp;
begin
  Result := TMeinTyp.Create;
  with Result do
  begin
    Property1 := 'Hallo 1';
    Property2 := 'Hallo 2';
    Property3 := 'Hallo 3';
    Property4 := 'Hallo 4';
    Property5 := 'Hallo 5';
    Property6 := 'Hallo 6';
    //...
  end;
end;

MaBuSE 2. Dez 2004 14:36

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Zitat:

Zitat von MaBuSE
Ich würde es so machen:
Delphi-Quellcode:
function meineFkt(str: String): TMeinTyp;
begin
  Result := TMeinTyp.Create;
  Result.Property1 := 'Hallo 1';
  Result.Property2 := 'Hallo 2';
end;

bzw etwas sicherer:

Delphi-Quellcode:
function meineFkt(str: String): TMeinTyp;
begin
  Result := TMeinTyp.Create;
  try
    Result.Property1 := 'Hallo 1';
    Result.Property2 := 'Hallo 2';
  except
    FreeAndNil(Result);
  end;
end;
Rückgabe = TMeinTyp
Rückgabe bei Fehler = nil

[edit]
Anwendung:
Delphi-Quellcode:
  ...
  x.Free; // nur um zu zeigen das x nicht definiert sein sollte/muss
  x := meineFunktion('');
  if x <> nil then
  try
    // mach was
  finally
    x.Free;
  end
  else Fehlermeldung.Ausgeben('...');
  ...
[/edit]

Luckie 2. Dez 2004 14:38

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Man könnte es auch als out Parameter deklarieren, wenn einem eine Deklaration als var Paamaeter nicht gefällt:
Delphi-Quellcode:
procedure FillSl(out sl: TStringList);
begin
  sl.Add('Foo');
  sl.Add('bar');
  sl.Add('Hello');
  sl.Add('world');
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  try
    FillSl(sl);
    Listbox1.Items.Assign(sl);
  finally
    FreeAndNil(sl);
  end;
end;

MaBuSE 2. Dez 2004 14:49

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Zitat:

Zitat von Luckie
Man könnte es auch als out Parameter deklarieren, wenn einem eine Deklaration als var Paamaeter nicht gefällt:
Delphi-Quellcode:
procedure FillSl(out sl: TStringList);
begin
  sl.Add('Foo');
  sl.Add('bar');
  sl.Add('Hello');
  sl.Add('world');
end;

Dann kanst Du aber nicht so was machen wie:

Delphi-Quellcode:
  ...
  with meineFkt('') do
  try
    // mach was mit den Properties
  finally
    Free;
  end;
  ...

changlee 3. Dez 2004 20:41

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Hallo!
Also nochmals vielen Dank dafür, dass Ihr euch alle so gut um mein Problem gekümmert habe.
Wie man result verwendet, weiß ich ja inzwischen, und eine gute Auswahl für die Werte-Rückgabe habe ich auch.

Also ich habe es inzwischen mit var-Parametern realisiert und es funktioniert.
Ich bin zwar im allgemeinen nicht so begeistert von solch einer Methode, da ich eher aus der Websieprogrammierung (PHP) komme. Dort war ich es gewohnt grundsätzlich mit Rückgabewerten zu arbeiten. Das geht ja wegen der Konsequenten Typunterscheidung bei Delphi nicht so schön (wie z.B. im Fehlerfall boolean sonst integer, vielleicht aber auch real und oder array :? ...).

Aber was ich ganz unschön finde ist dieses lästige erstellen und freigeben (MainTyp.Create..).
Vielleicht muss ich einfach mal einen Abend darüber nachdenken. Damit ich nachvollziehe, warum das alles nötig ist.

Was mich allerdings mal interessiert, ist, ob ihr eigentlich irgendwie kommerziell hier angestellt seid, oder ob ihr einfach nur hilfsbereit seid und wirklich bei Gelegenheit mal helfen wollt. Ich denke, dass ist eine Charaktereigenschaft, die in unserer Gesellschaft eigentlich zunehemend verloren geht.

Wenn ich eines Tages gut genug sein werde, hier auch mal eine Frage zu beantworten, dann habe ich wenigstens nicht mehr das Gefühl hier im Forum herumzuschmarotzen :lol:

Genug geredet.

mfg
changlee

Luckie 3. Dez 2004 21:04

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Ganz einfach. Instanzen von Klassen die du erzeugst belegen Speicher. Damit dieser Speicher wieder freigegeben wird, muss man die Instanzen wieder freigeben. Generell gilt: alles Ressourcen, die man selber belegt, muss man auch wieder freigeben. Das Gilt für Speicher, für Handles usw.

jim_raynor 4. Dez 2004 10:02

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Wenn du ein Variable vom einer Klasse hast zum Beispiel TFileStream, dann besitzt du nur einen Zeiger (4 Bytes) auf das Objekt. Erst mit dem Create wird das eigentlich Objekt erstellt. Fürs Freigeben siehe Luckies Beitrag ;)

P.S: Wenn man bei PHP konsequent mit Objekten arbeitet, hast du das dort auch.

MaBuSE 6. Dez 2004 09:29

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Zitat:

Zitat von changlee
Was mich allerdings mal interessiert, ist, ob ihr eigentlich irgendwie kommerziell hier angestellt seid, oder ob ihr einfach nur hilfsbereit seid und wirklich bei Gelegenheit mal helfen wollt. Ich denke, dass ist eine Charaktereigenschaft, die in unserer Gesellschaft eigentlich zunehemend verloren geht.

Hier ist keiner kommerziell angestellt !!!
Selbst die Moderatoren, die hier nach dem Rechten sehen, machen das unentgeltlich.
Es macht einfach Spaß sein Wissen weiterzugeben. Im Gegenzug bekommt man ja auch bei seinen Problemen geholfen. Das ist ein Geben und Nehmen.

Zitat:

Zitat von changlee
Wenn ich eines Tages gut genug sein werde, hier auch mal eine Frage zu beantworten, dann habe ich wenigstens nicht mehr das Gefühl hier im Forum herumzuschmarotzen :lol:

Schau mal genauer hin. Es gibt sicherlich auch schon einige Fragen zu denen Du eine Lösung (oder einen Lösungsansatz) hast. Keine Scheu, einfach mal antworten.

Viel Spaß

MathiasSimmack 6. Dez 2004 09:32

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
ot:
Zitat:

Zitat von MaBuSE
Es macht einfach Spaß sein Wissen weiterzugeben.

Oder so zu tun, als hätte man welches. :mrgreen:

MaBuSE 6. Dez 2004 09:43

Re: Rückgabewert von Funktionen / evtl. Problem mit try..fin
 
Zitat:

Zitat von MathiasSimmack
ot:
Zitat:

Zitat von MaBuSE
Es macht einfach Spaß sein Wissen weiterzugeben.

Oder so zu tun, als hätte man welches. :mrgreen:

Mist, ertappt :roll:


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