Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi eine Klasse als Rückgabewert?? (https://www.delphipraxis.net/87696-eine-klasse-als-rueckgabewert.html)

chaoslion 4. Mär 2007 19:48


eine Klasse als Rückgabewert??
 
Hey

ich hab ne Klasse:

Delphi-Quellcode:
type vector = class
public
 x,y: integer;
 function add(v:vector): vector;
end;


..

function vector.add(v:vector): vector;
begin
// wie mache ich das hier?
end;

wie gebe ich jetzt eine vector klasse zurück, die ich ja erst erstellen müsste mit vector.create aber wo gebe ich dann den speicher wieder
frei? wie macht man das?

leddl 4. Mär 2007 19:56

Re: eine Klasse als Rückgabetyp??
 
Lass den Nutzer deiner Funktion das ganze erledigen:

Delphi-Quellcode:
procedure vector.add(v : Vector; var ResultVector : Vector);
begin
...
ResultVektor := <Irgendwas>;
end;
//Edit:
Er muss dann vor dem Aufruf der Funktion ein Vektorobjekt erstellen und dies später auch wieder freigeben:

Delphi-Quellcode:
Var Result : Vector;
...
  Result := Vector.Create();

  v.add(u,Result);
 
  Result.Free;

sirius 4. Mär 2007 19:58

Re: eine Klasse als Rückgabetyp??
 
Ja, du kannst si in dieser add-funktion erstellen und später wieder freigen, wenn du sie in der aufrufenden funktion nicht mehr benötigst.
Wie dir ja auch aufgefallen ist, führt dies leicht zu Fehlern. Eine Alternative wäre die Klasse nicht als Funktionsergebnis zurückzugeben sondern sie als Parameter zu übergeben:
Delphi-Quellcode:
procedure add(v:vector;const to_add:vector);
begin
  to_add.dosomething;
end;
...

my_vector:=Tvector.create;
add(v,my_vector);
...
my_vector.free;
Damit hast du dann die Kontroll über den Speicher der Klasse an einer Stelle. aber sehe ies nur als Alternative. Es ist nicht immer möglich.


Roter Kaste: Ich habe mehr geschrieben :P

Muetze1 4. Mär 2007 22:08

Re: eine Klasse als Rückgabewert??
 
@leddl: Warum wird der Result Vektor als VAR deklariert und nicht als konstant? Schliesslich wird doch in der Funktion keine neue Instanz erzeugt oder dem Result Vektor zugewiesen. Beide Parameter können/sollten Const sein.

Elvis 5. Mär 2007 00:46

Re: eine Klasse als Rückgabewert??
 
Die IMHO schönere Lösung ist es eine Interface-Referenz zurückzugeben.
Dann wird der Speicher automatisch freigegeben wenn du die Referenz nicht mehr benutzt. :)

yankee 5. Mär 2007 06:02

Re: eine Klasse als Rückgabewert??
 
Du könntest auch den constructor überladen, dann ist wenigstens eindeutig, dass du ein neues Objekt zurückbekommst, dass du wieder freigeben musst.

Wenn du einen Parameter nicht mehr brauchst, wäre ich aber eher dafür du schreibst die Vektor-Klasse um und änderst die add-Funktion hinzu so, dass sie sich selbst modifiziert, statt eine geänderte Kopie von sich selbst.
Delphi-Quellcode:
procedure Vector.add(other: Vector);
begin
  x :=x+ other.x;
  y :=y+ other.y;
end;
Wenn du dann mal wirklich eine Kopie brauchst und den Parameter behalöten willst, dann klone das Objekt eben vorher.
Diese Lösung ist nicht nur übersichtlicher, sondern sollte auch performancetechnisch vorne liegen.

Elvis 5. Mär 2007 09:13

Re: eine Klasse als Rückgabewert??
 
Zitat:

Zitat von yankee
Diese Lösung ist nicht nur übersichtlicher, sondern sollte auch performancetechnisch vorne liegen.

Hmpf? Jetzt soll jeder Code plötzlich direkt mit der Klasse des Rückgabewertes verwoben werden?
Wo's 'n das übersichtlich und was hat es mit Performance zu tun ob ich Code im Constructor oder außerhalb platziere? :gruebel:

yankee 5. Mär 2007 14:17

Re: eine Klasse als Rückgabewert??
 
Zitat:

Zitat von Elvis
Wo's 'n das übersichtlich und was hat es mit Performance zu tun ob ich Code im Constructor oder außerhalb platziere? :gruebel:

Nix constructor...
Nix neue Klasse instanzieren.
Ich meinte, du sollst die bestehende Klasse abändern anstatt eine neue zu instanzieren...
DAS geht schneller, welch du... eben keinen neuen RAM ziehen musst und den Konstrukor nicht neu ziehen musst und dir einen Free-Aufruf sparst.
Das ganze hilft dir natürlich nur begrentzt, wenn due den alten Parameter brauchst. Aber selbst da würde ich es für übersichtlicher halten.

LarsMiddendorf 5. Mär 2007 15:09

Re: eine Klasse als Rückgabewert??
 
Warum in diesem Fall keinen record nehmen? Das ist bei einem Vektor eh sinnvoller und man kann Operatoren überladen.

mkinzler 5. Mär 2007 15:10

Re: eine Klasse als Rückgabewert??
 
Zitat:

Zitat von LarsMiddendorf
Warum in diesem Fall keinen record nehmen? Das ist bei einem Vektor eh sinnvoller und man kann Operatoren überladen.

Aber erst ab D10 (BDS2006/TD für Win32)

Flare 5. Mär 2007 15:15

Re: eine Klasse als Rückgabewert??
 
Zitat:

Zitat von mkinzler
Zitat:

Zitat von LarsMiddendorf
Warum in diesem Fall keinen record nehmen? Das ist bei einem Vektor eh sinnvoller und man kann Operatoren überladen.

Aber erst ab D10 (BDS2006/TD für Win32)

Also ich habe genau so wie es LarsMiddendorf beschrieben hat geschafft eine Vektorbibliothek auf Recordbasis zu basteln und habe das ganze in D7 gemacht. Oder was meinst du genau funktioniert nicht in Delphi kleiner 10?


Flare

mkinzler 5. Mär 2007 15:18

Re: eine Klasse als Rückgabewert??
 
Zitat:

Oder was meinst du genau funktioniert nicht in Delphi kleiner 10?
Class Operators

Flare 5. Mär 2007 16:35

Re: eine Klasse als Rückgabewert??
 
Zitat:

Zitat von mkinzler
Zitat:

Oder was meinst du genau funktioniert nicht in Delphi kleiner 10?
Class Operators

Stimmt, du hast Recht, ich hatte gedacht du hast deine Aussage auf den ersten Satz bezogen weil ich den 2. Satz irgendwie so schnell überflogen habe, dass ich den Inhalt nicht aufgenommen habe.
Ich habe das mit überladenen Funktionen gelöst, mit überladenen Operatoren wäre es natürlich um einiges komfortabler gewesen.


Flare

Muetze1 5. Mär 2007 18:28

Re: eine Klasse als Rückgabewert??
 
... aber Funktionen/Procedure innerhalb von Records (also nicht als Prototype sondern als Implementation) ist mit den älteren Delphi's (kleiner D8) auch nicht möglich.

yankee 5. Mär 2007 20:14

Re: eine Klasse als Rückgabewert??
 
Zitat:

Zitat von Muetze1
... aber Funktionen/Procedure innerhalb von Records (also nicht als Prototype sondern als Implementation) ist mit den älteren Delphi's (kleiner D8) auch nicht möglich.

Ich dachte immer, dass heisst dann Klasse ^^.
Wo is'n da der Unterschied? Ist das dann eine Klasse, die man nicht instanzieren und freen muss?

Ghostwalker 6. Mär 2007 06:10

Re: eine Klasse als Rückgabewert??
 
Ok....kleines Beispiel:


Record mit überladenen Operatoren:

Delphi-Quellcode:
   Type
      TVector = record
                    x,y,z : integer
                 class operator Add(a,b:TVector):TVector;
                end;

      :
   Implementation

    Class Operator TVector.add(a,b:TVector):TVector;
    begin
      result.x := a.x+b.x;
      result.y := a.y+b.y;
      result.z := a.z+b.z;
    end;
Die Verwendung sieht dann so aus:

Delphi-Quellcode:
     procedure TForm1.Button1click(Sender:TObject);
     var
       v1,v2,v3 : TVector;

     begin
       //Einfach mal werte eintrag;
       v1.x := 10;
       v1.y := 20;
       v1.z := 30;
       
       v2.x := 5;
       v2.y := 50;
       v2.z := 33;

       v3 := v1+v2;    
     end;
Das ganze funktioniert, wie bereits erwähnt, ab BDS2006 und mit den Turbos. Du brauchst also auch keine Klassen instanziieren und wieder freigeben.


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