Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   TObjectList sauber an function übergeben und wieder zurück (https://www.delphipraxis.net/204884-tobjectlist-sauber-function-uebergeben-und-wieder-zurueck.html)

norwegen60 10. Jul 2020 13:41

AW: TObjectList sauber an function übergeben und wieder zurück
 
Ich weiß keinen Weg, wie ich um 3 Instanzen rum komme
Was ich machen muss sind diverse Rechenschritte Wie z.B.
  1. Korrektur um einen zu berechnenden Wert
  2. Averaging über die X rechts und links liegenden Werte in der Liste
  3. Ableitung nach Savitzky/Golay
Instanz 1 enthält die Ausgangsdaten die nicht verändert werden sollen
Instanz 2 enthält die zuletzt berechneten Werte
Instanz 3 enthält die aktuell berechneten Werte

Bei 1. ist es keine Problem zu sagen Instanz2[i].Value := Instanz2[i].Value + 6 (hier reichen 2 Instanzen)
Bei 2. und 3. gibt es aber das Problem, dass ich z.B. sage Instanz3[i].Value := (Instanz2[i-1].Value + Instanz2[i].Value + Instanz2[i+1].Value)/3 (Mittelwert über drei Werte)

Würde ich nur mit Instanz2 arbeiten, wäre der Wert Instanz2[i-1] im vorigen Loop schon geändert.
Instanz1 funktioniert auch nicht, da Instanz2 in Berechnung 1. schon geändert wurde somit auf Instanz2 weitergemachet werden muss
Ich hoffe es ist jetzt etwas klarer

Stevie 10. Jul 2020 14:39

AW: TObjectList sauber an function übergeben und wieder zurück
 
Und deshalb mag ich interface basierte Collections so - da braucht man sich um so Zeugs gar nicht kümmern:

Delphi-Quellcode:
{$APPTYPE CONSOLE}

uses
  Spring.Collections,
  SysUtils;

type
  TTest = class
  private
    FValue: Double;
  public
    property Value: Double read FValue write FValue;
  end;

  ITestList = IList<TTest>;

function CopyTestList(const SourceList: ITestList): ITestList;
var
  i: Integer;
  lTest: TTest;
begin
  Result := TCollections.CreateObjectList<TTest>(True);

  for i := 0 to SourceList.Count - 1 do
  begin
    lTest := TTest.Create;
    lTest.Value := SourceList[i].Value;
    Result.Add(lTest);
  end;
end;

function DoAdding(const SourceList: ITestList): ITestList;
var
  i: Integer;
begin
  Result := CopyTestList(SourceList);

  for i := 0 to Result.Count - 1 do
    Result[i].Value := Result[i].Value + 5;
end;

function DoMultiplicate(const SourceList: ITestList): ITestList;
var
  i: Integer;
begin
  Result := CopyTestList(SourceList);

  for i := 0 to Result.Count - 1 do
    Result[i].Value := Result[i].Value * 5;
end;

var
  FlagAddieren: Boolean;
  FlagMultiplicate: Boolean;

function DoCalculations(const SourceList: ITestList): ITestList;
var
  temp: ITestList;
begin
  temp := SourceList;

  if FlagAddieren then
    temp := DoAdding(temp);

  if FlagMultiplicate then
    temp := DoMultiplicate(temp);

  Result := temp;
end;

procedure Start;
var
  i: Integer;
  lStartList, lResultList: ITestList;
  lTest: TTest;
begin
  lStartList := TCollections.CreateObjectList<TTest>(true);

  for i := 1 to 5 do
  begin
    lTest := TTest.Create;
    lStartList.Add(lTest);
    lTest.Value := i;
  end;

  FlagAddieren := True;
  FlagMultiplicate := True;
  lResultList := DoCalculations(lStartList);

  for lTest in lResultList do
    Writeln(lTest.Value.ToString);
end;

begin
  try
    Start;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

norwegen60 10. Jul 2020 17:58

AW: TObjectList sauber an function übergeben und wieder zurück
 
Zitat:

Zitat von Stevie (Beitrag 1469306)
Und deshalb mag ich interface basierte Collections so - da braucht man sich um so Zeugs gar nicht kümmern:

WOW, jetzt sind wir ganz nah dort wie ich es mir mit functions vorgestellt habe. Einziges Problem. Ich habe noch nie mit Interfaces gearbeitet. Eigenlich sieht es ja sehr ähnlich aus.

Kurz zusammengafasst:
  • lStartList wird in Start erzeugt
  • Alle anderen Listen werden in CopyTestList erzeugt
  • Aber wer kümmert sich um das Free. Denn wenn ich durch bin, sind drei Listen erzeugt, arbeiten tu ich aber letztlich nur mit lStartList und lResultList. Und wenn ich mit der fertig bin, was mach ich mit der? Auch lResultList.Free; Und die Elemente in der lResultList sind dann auch all freigegeben? Und was ist mit der Liste, die in DoAdding erzeugt wurde?

Normale TObjectList funktionieren ja auch ohne Free. Ich muss mich dann nur nicht wundern wenn irgenwann der Speicher voll ist. Wer also kümmert sich hier um das Free?

TurboMagic 10. Jul 2020 20:06

AW: TObjectList sauber an function übergeben und wieder zurück
 
Das ist doch genau der Gag an Interfaces in Delphi: Free ist nicht nötig.
Die sind referenzgezählt und wenn keiner mehr auf die InterfaceReferenz
zeigt geht die auf 0 und das Interface wird freigegeben.

Nur eines darf man nicht tun: das Interface als Objektreferenz erzeugen und
sowohl als Interface- und Objektreferenz benutzen und dann die Objektreferenz
mit Free freigeben. Das knallt dann, weil man dem Interface dadurch hinter
dem Rücken das Ding freigibt.

Also wenn Interface, dann immer nur über Interface Referenzen benutzen!

Grüße
TurboMagic

norwegen60 11. Jul 2020 09:24

AW: TObjectList sauber an function übergeben und wieder zurück
 
Zitat:

Zitat von TurboMagic (Beitrag 1469328)
Nur eines darf man nicht tun: das Interface als Objektreferenz erzeugen und sowohl als Interface- und Objektreferenz benutzen und dann die Objektreferenz mit Free freigeben.

Meinst du sowas:

Delphi-Quellcode:
type
  ITestList = IList<TTest>;

function SoJa:ITestList;
begin
  Result := TCollections.CreateObjectList<TTest>(True);
end;

function SoNie:ITestList;
begin
  Result := ITestList.Create;
end;

Procedure Start;
var
  lTest:ITestList;
begin
  lTest := SoNie;
  lTest.Free;

  // So was darf man? Ist aber unnötig, da beim Verlassen von Start lTest sowieso freigegeben wird
  lTest := SoJa;
  lTest.Free;
end;

DeddyH 11. Jul 2020 10:06

AW: TObjectList sauber an function übergeben und wieder zurück
 
Vergiss das Free einfach im Zusammenhang mit referenzgezählten Interfaces. Die Instanz wird ganz automatisch freigegeben, wenn der letzte Verweis auf sie ungültig wird, sei es, dass die Variable aus dem Scope läuft oder explizit auf nil gesetzt wird.

himitsu 11. Jul 2020 10:14

AW: TObjectList sauber an function übergeben und wieder zurück
 
Beides nicht .... KEIN Free,

Ob man aber das letzte
Delphi-Quellcode:
lTest := nil;
macht oder nicht, das ist egal, aber entspricht deinen Kommentaren.
Und selbst das Erste wäre nicht nötig.

Stevie 11. Jul 2020 11:07

AW: TObjectList sauber an function übergeben und wieder zurück
 
Interfaces haben kein
Delphi-Quellcode:
Create
oder
Delphi-Quellcode:
Free
, damit erübrigt sich die Frage ob man das machen sollte oder nicht.

Die Spring4D Collections sind so designed, dass du niemals mit den implementierenden Klassen in Berührung kommst, du erzeugst sie alle über die entsprechenden Methoden auf
Delphi-Quellcode:
TCollections
aus der Unit
Delphi-Quellcode:
Spring.Collections
. Niemals z.B.
Delphi-Quellcode:
Spring.Collections.Lists
ins uses und selbst
Delphi-Quellcode:
TList<TTest>.Create
machen.

mytbo 11. Jul 2020 11:57

AW: TObjectList sauber an function übergeben und wieder zurück
 
Zitat:

Zitat von Stevie (Beitrag 1469350)
Die Spring4D Collections sind so designed, dass du niemals mit den implementierenden Klassen in Berührung kommst, du erzeugst sie alle über die entsprechenden Methoden auf
Delphi-Quellcode:
TCollections
aus der Unit
Delphi-Quellcode:
Spring.Collections
. Niemals z.B.
Delphi-Quellcode:
Spring.Collections.Lists
ins uses und selbst
Delphi-Quellcode:
TList<TTest>.Create
machen.

Ich verwende seit Kurzem Spring4D und DSharp. Habe bis jetzt gedacht, dass ich alles an Infos gegoogelt habe. Und ganz zufällig erfahre ich hier, dass ich wohl auf das falsche DSharp Beispiel "Sample7.Main" gesetzt habe. :roll:

Bis bald...
Thomas

Stevie 11. Jul 2020 15:22

AW: TObjectList sauber an function übergeben und wieder zurück
 
Zitat:

Zitat von mytbo (Beitrag 1469362)
Und ganz zufällig erfahre ich hier, dass ich wohl auf das falsche DSharp Beispiel "Sample7.Main" gesetzt habe. :roll:

Touché, stammt vermutlich noch aus der Zeit, als DSharp selber noch interface basierte Collections hatte und kompiliert derzeit nicht mal - von daher jo, bestimmt das falsche Beispiel.
Aber wenn es sonst außer nem ironischen Seitenhieb nichts zu klagen gibt, dann bin ich ja froh :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:47 Uhr.
Seite 2 von 2     12   

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