![]() |
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? |
Re: eine Klasse als Rückgabetyp??
Lass den Nutzer deiner Funktion das ganze erledigen:
Delphi-Quellcode:
//Edit:
procedure vector.add(v : Vector; var ResultVector : Vector);
begin ... ResultVektor := <Irgendwas>; end; 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; |
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:
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.
procedure add(v:vector;const to_add:vector);
begin to_add.dosomething; end; ... my_vector:=Tvector.create; add(v,my_vector); ... my_vector.free; Roter Kaste: Ich habe mehr geschrieben :P |
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.
|
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. :) |
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:
Wenn du dann mal wirklich eine Kopie brauchst und den Parameter behalöten willst, dann klone das Objekt eben vorher.
procedure Vector.add(other: Vector);
begin x :=x+ other.x; y :=y+ other.y; end; Diese Lösung ist nicht nur übersichtlicher, sondern sollte auch performancetechnisch vorne liegen. |
Re: eine Klasse als Rückgabewert??
Zitat:
Wo's 'n das übersichtlich und was hat es mit Performance zu tun ob ich Code im Constructor oder außerhalb platziere? :gruebel: |
Re: eine Klasse als Rückgabewert??
Zitat:
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. |
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.
|
Re: eine Klasse als Rückgabewert??
Zitat:
|
Re: eine Klasse als Rückgabewert??
Zitat:
Flare |
Re: eine Klasse als Rückgabewert??
Zitat:
|
Re: eine Klasse als Rückgabewert??
Zitat:
Ich habe das mit überladenen Funktionen gelöst, mit überladenen Operatoren wäre es natürlich um einiges komfortabler gewesen. Flare |
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.
|
Re: eine Klasse als Rückgabewert??
Zitat:
Wo is'n da der Unterschied? Ist das dann eine Klasse, die man nicht instanzieren und freen muss? |
Re: eine Klasse als Rückgabewert??
Ok....kleines Beispiel:
Record mit überladenen Operatoren:
Delphi-Quellcode:
Die Verwendung sieht dann so aus:
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;
Delphi-Quellcode:
Das ganze funktioniert, wie bereits erwähnt, ab BDS2006 und mit den Turbos. Du brauchst also auch keine Klassen instanziieren und wieder freigeben.
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; |
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