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 Function freigeben (https://www.delphipraxis.net/41062-rueckgabewert-von-function-freigeben.html)

LoL 25. Feb 2005 10:25


Rückgabewert von Function freigeben
 
hallo

folgendes:
ich habe eine Function mir was vom Typ TComponent zurück gibt:

Delphi-Quellcode:
function CurrentOL : TComponent;
begin
  if ... then result := EineKomponente
  else result := EineAndereKompoente;
end;
Warum kann ich nun die Procedure FreeAndNil(CurrentOL) nicht anwenden?
Fehler: Constant object cannot be passed as var parameter
wie kann ich die zurückgegeben komponente freigeben?

2. Wie kann ich dann mit der zurückgegebenen komponente wieder eine TComponent erstellen
(CurrentOL := TComponent.Create(form1);) das geht ja nicht...


Ist vielleicht ein bisschen komisch erklärt aber wenn ihr fragen habt :mrgreen: einfach fragen

KrasserChecker 25. Feb 2005 10:28

Re: Rückgabewert von Function freigeben
 
FreeAndNil erwartet einen VAR-Parameter. D.h. die Funktion will den übergebenen Wert ändern (schließlich setzt die Methode die übergebene Variable auf "nil").
Einer Funktion kann kein Wert zugewiesen werden, daher kannst Du deine Funktion auch nicht direkt an FreeAndNil weitergeben.
Lösung:

Delphi-Quellcode:
var temp: TObject;
begin
  temp := CurrentOL;
  FreeAndNil(temp);
end;
Zitat:

(CurrentOL := TComponent.Create(form1) das geht ja nicht...
siehe oben (Einer Funktion kann kein Wert zugewiesen werden)

Bernhard Geyer 25. Feb 2005 10:29

Re: Rückgabewert von Function freigeben
 
Zitat:

Zitat von LoL
Warum kann ich nun die Procedure FreeAndNil(CurrentOL) nicht anwenden?
Fehler: Constant object cannot be passed as var parameter

Dann schau mal die Implementierung von FreeAndNil an. Dort wird der übergebene Parameter auf nil gesetzt.
Und das wird schlecht für eine Funktion gehen.

Zitat:

Zitat von LoL
wie kann ich die zurückgegeben komponente freigeben?

Delphi-Quellcode:
CurrentOL.Free
Zitat:

Zitat von LoL
Wie kann ich dann mit der zurückgegebenen komponente wieder eine TComponent erstellen

Versteh ich nicht. Die Funktion CurrentOL liefert doch eine TComponent-Instanz zurück?

LoL 25. Feb 2005 10:36

Re: Rückgabewert von Function freigeben
 
ok erst mal danke.
das freigeben hab ich jetzt schon verstanden.

jetzt will ich nachdem ich sie freigegeben habe wieder "erstellen" also zurückgegebene variable := TComponent.create(form1)

KrasserChecker 25. Feb 2005 10:39

Re: Rückgabewert von Function freigeben
 
Stell doch deine Methode einfach auf einen Var-Parameter um:
Delphi-Quellcode:
procedure CurrentOL(var Value : TComponent);
begin
  if ... then Value := EineKomponente
  else Value := EineAndereKompoente;
end;

procedure DoSomething;
var temp: TObject;
begin
  CurrentOL(temp);
  temp.Free;
  temp := TIrgendwas.Create(form1);
end;
Nein, vergiss es, mal wieder erst geschrieben und dann nachgedacht. Dadurch schreibst den neuen Zeiger ja nicht in die alte Variablen (EineKomponente oder EineAndereKompoente). :wall:

LoL 25. Feb 2005 10:45

Re: Rückgabewert von Function freigeben
 
genau das war ja eigentlich meine frage ich arbeite ja nur mit der temnporären kompoente und das wird ja nicht auf die ursprünglich komponente übertrangen :wink:

himitsu 25. Feb 2005 10:49

Re: Rückgabewert von Function freigeben
 
Du könntest ja auch mit Zeigern arbeiten?


Also in etwa so:
Delphi-Quellcode:
function CurrentOL : Pointer;
begin
  if ... then result := @EineKomponente
  else result := @EineAndereKompoente;
end;


FreeAndNil(CurrentOL^);

KrasserChecker 25. Feb 2005 10:51

Re: Rückgabewert von Function freigeben
 
Richtig, wollte ich auch gerade sagen. HAbe nur zu langsam :coder:

Delphi-Quellcode:
function CurrentOL: Pointer;
begin
  if ... then Result := @EineKomponente
  else Result := @EineAndereKompoente;  
end;

procedure DoSomething;
var temp: Pointer;
begin
  temp := CurrentOL;
  temp^.Free;
  temp := TIrgendwas.Create(form1);
end;

alcaeus 25. Feb 2005 10:54

Re: Rückgabewert von Function freigeben
 
Kann mir das mal jemand erklären?

nehmen wir an ich hätte folgende Funktion:

Delphi-Quellcode:
function Foo: TBitmap;
begin
  Result := TBitmap.Create;
end;
Wenn ich nun das mache:

Delphi-Quellcode:
var
  B: TBitmap;
begin
  B := Foo;
  B.Free;
end;
Theoretisch müsste wohl B freigegeben werden, also das Objekt das "Foo" erstellt hat, schließlich wird das Objekt bei den Zuweisungen nicht kopiert, oder doch?

Greetz
alcaeus

himitsu 25. Feb 2005 10:58

Re: Rückgabewert von Function freigeben
 
Ja alcaeus, so klappt es, aber da in diesem fall nicht .Free, sonder Funktion FreeAndNil verwendet wird, wird eine Variable benötogt und Funktionen lievern nunmal Konstanten als unktionsergebnis.

alcaeus 25. Feb 2005 11:02

Re: Rückgabewert von Function freigeben
 
Heißt das, dass dieser Code:

Delphi-Quellcode:
var
  B: TBitmap;
begin
  B := Foo;
  FreeAndNil(B);
end;
Gegen die Wand laufen würde? Ich dachte immer die Objektvariable sei nur ein Pointer auf das Objekt? :gruebel:

Greetz
alcaeus

LoL 25. Feb 2005 11:53

Re: Rückgabewert von Function freigeben
 
Delphi-Quellcode:
var comp : TComponent;

procedure TForm1.Button1Click(Sender: TObject);
var p : Pointer;
begin
  p.free;
  p := @comp;
  p := TComponent.Create(form1);
  if comp = nil then showmessage('NIL');
end;
Die Komponente comp ist danach aber immer noch NIL?!? :gruebel:

himitsu 25. Feb 2005 12:43

Re: Rückgabewert von Function freigeben
 
@LoL:
Wie ich schonmal sagte, das Problem ist hier einfach nur, dass FreeAndNil eine Variable als Parameter haben will und eine Function als Funktionsergebnis eben nur sowas wie eine Konstante zurückgibt.

Demnach geht folgendes eben nicht.

Code:
procedure CurrentOL(var Value : TComponent);
begin
  if ... then Value := EineKomponente
  else Value := EineAndereKompoente;
end;

[color=#ff0000]FreeAndNil(CurrentOL);[/color]
Aber wie man oben schön sieht gibt es viele Möglichkeiten dieses zu umgehen.
- über Pointer
- über 'ne zusätliche Variable
- ...

LoL 25. Feb 2005 12:47

Re: Rückgabewert von Function freigeben
 
ich beziehe mich jetzt auf mein beispiel direkt über deinem post...
warum ist die componente die auf die der pointer zeigt nil?

himitsu 25. Feb 2005 12:57

Re: Rückgabewert von Function freigeben
 
Das ist das Problem, wenn man mit den Pointern Falsch umgeht :zwinker:

Ich hoffe so geht es: (hab ja selber noch nicht alle Tricks drauf)
Code:
procedure TForm1.Button1Click(Sender: TObject);
var p : Pointer;
begin
  p.free;
  p := @comp;
  p := [color=#ff0000]@[/color]TComponent.Create(form1);
  if comp = nil then showmessage('NIL');
end;
[add]
neee, ich glaub so geht es auch nicht, aber sowas in der Richtung muß es wohl sein

aber p.Free ist eh falsch.

So sollte es an dieser Stelle wohl richtiger sein:
Delphi-Quellcode:
var p : Pointer;

p^.Free;
TCompunent(p^).Free;

LoL 25. Feb 2005 13:02

Re: Rückgabewert von Function freigeben
 
das geht gar nicht dann kommt variable required...
müsste das aber wenn dann nicht umgekehrt sein? war das nicht irgendwie so dass man dazu den pointer dereferenzieren muss

Oxmyx 25. Feb 2005 13:32

Re: Rückgabewert von Function freigeben
 
Wie schon gesagt besteht die einzige Möglichkeit darin, den Rückgabewert der Funktion einer Objektvariablen zuzuweisen und dann den Destruktor des Objekts aufzurufen (oder eben FreeAndNil).

Das ganze Gerede um Zeiger in dem Thread hier ist zumeist falsch, darüber hinaus wird in Delphi ein Objekt grundsätzlich dynamisch instantiiert, die Objektvariable ist also nichts weiter als ein typisierter Zeiger.

LoL 25. Feb 2005 13:34

Re: Rückgabewert von Function freigeben
 
ich hab es nun:

Delphi-Quellcode:
var comp : TComponent;

procedure TForm1.Button1Click(Sender: TObject);
var p : Pointer;
begin
  p := @comp;
  TComponent(p^).free;
  TComponent(p^) := TComponent.Create(form1);
  if comp = nil then showmessage('NIL');
end;

Oxmyx 25. Feb 2005 13:49

Re: Rückgabewert von Function freigeben
 
Zitat:

Zitat von LoL
ich hab es nun:

Delphi-Quellcode:
var comp : TComponent;

procedure TForm1.Button1Click(Sender: TObject);
var p : Pointer;
begin
  p := @comp;
  TComponent(p^).free;
  TComponent(p^) := TComponent.Create(form1);
  if comp = nil then showmessage('NIL');
end;

Wieso denn das? Das rumgezeigere da ist doch komplett unnötig.

LoL 25. Feb 2005 14:00

Re: Rückgabewert von Function freigeben
 
also ich erklär mal wozu ich das brauche:

ich verwende die Komponente TChart. dort habe ich mehrere graphen. zu jedem graph habe ich eine art Object liste weil ich an den graphen teilweise edits und andere komponenten positionieren muss. nun brauche ich eine funktion die mir die aktuelle objectlsite zurück gibt in abhängikeit davon welche series gerade bearbeitet wird. ich will das mit einer funktion machen da ich direkt mit dem zurückgegebenen wert der funktion arbeiten will.

Oxmyx 25. Feb 2005 14:08

Re: Rückgabewert von Function freigeben
 
Eine Objektvariable ist aber bereits ein typisierter Zeiger!. Noch einmal mit einem Zeiger auf eine Objektvariable zu verweisen, ist schlicht Unsinn.

LoL 28. Feb 2005 10:35

Re: Rückgabewert von Function freigeben
 
also nochmal zurück ich habe das bisher immer noch nicht lösen könenen:
ich bräcuchte enventuell mal ne erklärung dazu:

Delphi-Quellcode:
var c1,c2 : TComponent;
    b : boolean;

function muh : TComponent;
begin
  result := nil;
  if b then
    result := c1
  else
    result := c2;
end;

procedure TForm1.Button1Click(Sender: TObject);
var cur : TComponent;
begin
  b := true;

  cur := muh;

  if @c1 <> @cur then showmessage('ungleich');
end;
warum ist wenn ich den button drück c1 und cur ungleich?

soweit ich das verstanden habe ist c1 doch auch nichts anderes als ein zeiger auf eine adresse oder? und cur bekommt dann den zeiger zugewiesen. warum sind die addressen dann unterschiedlich?

himitsu 28. Feb 2005 10:54

Re: Rückgabewert von Function freigeben
 
hmmm, versuch's mal so ... ich c1 un cur sind ja eingenständige Variablen, in denen die Pointer gespeichert werden, also haben @c1 und @cur auch immer unterschiedliche Adressen.

Delphi-Quellcode:
var c1,c2 : TComponent;
    b : boolean;

function muh : [color=#ff0000]Pointer[/color];
begin
  result := nil;
  if b then
    result := [color=#ff0000]@[/color]c1 
  else
    result := [color=#ff0000]@[/color]c2;
end;

procedure TForm1.Button1Click(Sender: TObject);
var cur : Pointer;
begin
  b := true;

  cur := muh;

  if @c1 <> cur then showmessage('ungleich');
end;
oder so
Delphi-Quellcode:
var c1,c2 : TComponent;
    b : boolean;

function muh : TComponent;
begin
  result := nil;
  if b then
    result := c1 
  else
    result := c2;
end;

procedure TForm1.Button1Click(Sender: TObject);
var cur : TComponent;
begin
  b := true;

  cur := muh;

  if c1 <> cur then showmessage('ungleich');
end;

LoL 28. Feb 2005 11:04

Re: Rückgabewert von Function freigeben
 
erstma danke für deine hilfe :thumb:

folgendes zu deinem ersten beispiel die zeiger sind jetzt gleich(zumindest die addressen).
dann müsste doch logischer weise wenn ich
Delphi-Quellcode:
  cur := TComponent.Create(form1);
auch c1 <> nil sein oder? ist es aber nicht! woran liegt das?

himitsu 28. Feb 2005 11:14

Re: Rückgabewert von Function freigeben
 
nee, beim 1. sind das ja die Zeiger auf die Variable (glaub ich), und da c1 und c2 immer nur auf vie Variable zeigen, sollte es dann wohl so aussehn.
Delphi-Quellcode:
if cur^ <> nil then ...

LoL 28. Feb 2005 11:19

Re: Rückgabewert von Function freigeben
 
kann ich denn die funktion so schreiben das mit dem rückgabe wert der funktion(also eine komponente) so arbeiten kann als ob es die ursprünglich variable wäre?

Delphi-Quellcode:
cur = muh;
cur := TComponent.Create;
cur.Free;
//usw.
dabei soll aber immer c1 bzw c2 verändert werden?

himitsu 28. Feb 2005 11:35

Re: Rückgabewert von Function freigeben
 
Klar, indem du es so machst, wie in deinem ersten Code,
Delphi-Quellcode:
function CurrentOL : TComponent;
begin
  if ... then result := EineKomponente
  else result := EineAndereKompoente;
end;
nur dann kannst du das ergebnis wiederum nicht direckt an ein andere Fumktion übergeben, welche einen Var-Parameter haben will (wie z.B. an FreeAndNil)

LoL 28. Feb 2005 11:48

Re: Rückgabewert von Function freigeben
 
ok

Delphi-Quellcode:
var c1,c2 : TComponent;
    b : boolean;

function CurrentOL : TComponent;
begin
  if b then result := c1
  else result := c2;
end;

procedure TForm1.Button1Click(Sender: TObject);
var cur : TComponent;
begin
  b := true;

  cur := CurrentOL;
  cur := TComponent.Create(form1);

  if c1 = nil then showmessage('nil');
end;
c1 ist aber hier nach immer noch nil! Woran kann das liegen?

PRehders 28. Feb 2005 11:59

Re: Rückgabewert von Function freigeben
 
Hallo LoL,

es ist doch klar, dass c1 = NIL ist: Du weist c1 nirgendwo einen Wert zu oder übergibt es als VAR-Parameter an eine Prozedur. Woher sollte denn ein Wert kommen?
Dadurch, dass du über deine Funktion c1 an cur zuweist, kommt ja keine interne Kopplung zustande, die bei der Zuweisung an cur (via Create) auch auf c1 "durchschlägt".

Bis dann

Peter

LoL 28. Feb 2005 12:39

Re: Rückgabewert von Function freigeben
 
aber wie kann ich das dann regeln das ich den wert der funktion verändere oder ist das nicht möglich?


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