AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi TObjectList-Object da, aber beim Zugriff Stack-Overflow
Thema durchsuchen
Ansicht
Themen-Optionen

TObjectList-Object da, aber beim Zugriff Stack-Overflow

Ein Thema von Captnemo · begonnen am 18. Jan 2016 · letzter Beitrag vom 3. Feb 2016
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#1

TObjectList-Object da, aber beim Zugriff Stack-Overflow

  Alt 18. Jan 2016, 14:27
Hi,

ich habe eine TObjectList nach diesem Schema:
Delphi-Quellcode:
type
  TTemperatur=class
  private
    FTemp: Extended;
    FId: string;
    procedure SetId(const Value: string);
    procedure SetTemp(const Value: Extended);
  public
    constructor Create;
    procedure WriteToStream(st: TStream);
    procedure LoadFromStream(st: TStream);
  published
    property Id: string read FId write SetId;
    property Temp: Extended read FTemp write SetTemp;
  end;

type
  TTemperaturList=class(TObjectList)
    function getItem(index: Integer): TTemperatur; virtual;
    procedure setItem(index: Integer; Temperatur: TTemperatur); virtual;
  public
    property Items[index: Integer]: TTemperatur read getItem write setItem; default;
    procedure Insert(index: Integer; Temperatur: TTemperatur); virtual;
    function Add(Temperatur: TTemperatur): Integer; virtual;
    function Remove(Temperatur: TTemperatur): Integer; virtual;
    function IndexOf(Temperatur: TTemperatur): Integer; virtual;
    function First: TTemperatur; virtual;
    function Last: TTemperatur; virtual;
    procedure WriteToStream(st: TStream);
    procedure LoadFromStream(st: TStream);
    function IndexOfId(value: string): Integer; virtual;
  end;

type
  TRaspberry=class
  private
    FName: string;
    FTemp: TTemperaturList;
    FIP: string;
    procedure SetIP(const Value: string);
    procedure SetName(const Value: string);
    procedure SetTemp(const Value: TTemperaturList);
  public
    constructor Create;
    destructor Destroy;
    procedure WriteToStream(st: TStream);
    procedure LoadFromStream(st: TStream);
  published
    property Name: string read FName write SetName;
    property IP: string read FIP write SetIP;
    property Temp: TTemperaturList read FTemp write SetTemp;
  end;

type
  TRaspberryList=class(TObjectList)
    function getItem(index: Integer): TRaspberry; virtual;
    procedure setItem(index: Integer; Raspberry: TRaspberry); virtual;
  public
    property Items[index: Integer]: TRaspberry read getItem write setItem; default;
    procedure Insert(index: Integer; Raspberry: TRaspberry); virtual;
    function Add(Raspberry: TRaspberry): Integer; virtual;
    function Remove(Raspberry: TRaspberry): Integer; virtual;
    function IndexOf(Raspberry: TRaspberry): Integer; virtual;
    function First: TRaspberry; virtual;
    function Last: TRaspberry; virtual;
    procedure WriteToFile(Filename: string);
    procedure LoadFromFile(Filename: string);
    function IndexOfIP(value: string): Integer; virtual;
  end;
Explizit geht es um die Funktion:
Delphi-Quellcode:
function TTemperaturList.IndexOfId(value: string): Integer;
var
  I: Integer;
begin
  Result:=-1;
  for I := 0 to self.Count-1 do
    if self[I].Id=value then
    begin
      Result:=I;
      Exit;
    end;
end;
der TTemperaturList.

Jetzt sollen mit folgender Prozedur TTemperatur-Items hinzugefügt, bzw. wenn sie schon vorhanden sind, geändert werden:
Delphi-Quellcode:
procedure TfrmMain.btn1Click(Sender: TObject);
var
  r, t: integer;
  Raspberry: TRaspberry;
  Temp: TTemperatur;
  FIP, FId: string;
  FTemperatur: Extended;
begin
  FIP:='192.168.0.110';
  FId:='28-000444e3ba3ff';
  FTemperatur:=19.937;
  r:=FRaspberrys.IndexOfIP(FIP);
  if r>-1 then
  begin
    Raspberry:=FRaspberrys[r];
  end else begin
    Raspberry:=TRaspberry.Create;
    FRaspberrys.Add(Raspberry);
  end;
  if Raspberry<>nil then
  begin
    t:=Raspberry.Temp.IndexOfId(FId); //<---Hier tritt beim zweiten durchlauf dann die Exception auf.
    if t>-1 then
    begin
      Temp:=Raspberry.Temp[t];
    end else begin
      Temp:=TTemperatur.Create;
      Raspberry.Temp.Add(Temp);
    end;
    if Temp<>nil then
    begin
      Temp.Id:=FId;
      Temp.Temp:=FTemperatur;
    end;
  end;
end;
Ein TRaspberry wird manuell erzeugt, ist also vorhanden.

Beim TTemperaturList.IndexOfId(value: string) kommt es beim zweiten Aufruf der btn1Click zu einem Stackoverflow. Klar beim ersten mal wird das neue Objekt TTemperatur angelegt, weil eben noch keines vorhanden ist.
Beim zweiten Mal müsste er es ja finden, da die Id die gleich ist. Komischerweise wird in der IndexOfId als Count auch 1 ausgegeben, aber auf das Object kann ich nicht zugreifen. Also irgendwo hab ich einen Denkfehler, aber ich finde ich einfach nicht.
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#2

AW: TObjectList-Object da, aber beim Zugriff Stack-Overflow

  Alt 18. Jan 2016, 14:43
ich habe eine TObjectList nach diesem Schema:
Einen Grund für den Absturz konnte ich noch nicht sehen. Vielleicht können wir es besser reproduzieren wenn der Code auf ein minimales Beispiel reduziert wird?

Robuster wäre es die Containerklasse nicht von der Klasse TObjectList abzuleiten sondern eine interne (private) TObjecList Instanz zu benutzen. Das entkoppelt die API der TObjectList und sichert den Client-Code besser gegen "versehentliche" Verwendung von TObjectList Methoden ab. Das könnte auch für die konkrete Fehlersuche hilfreich sein.
Michael Justin
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#3

AW: TObjectList-Object da, aber beim Zugriff Stack-Overflow

  Alt 18. Jan 2016, 14:47
Danke für deine Hilfe. Den eigentlichen Fehler habe ich mittlerweile gefunden: es war lediglich ein fehlendes inherited beim Zugriff auf das TTemperaturobjekt.

wäre es die Containerklasse nicht von der Klasse TObjectList abzuleiten sondern eine interne (private) TObjecList Instanz zu benutzen. Das entkoppelt die API der TObjectList und sichert den Client-Code besser gegen "versehentliche" Verwendung von TObjectList Methoden ab. Das könnte auch für die konkrete Fehlersuche hilfreich sein.
Aber wenn du mir das noch mal anders erläutern könntest, wäre ich dir sehr dankbar, denn ich weiß im Augenblick nicht was du damit meinst.
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#4

AW: TObjectList-Object da, aber beim Zugriff Stack-Overflow

  Alt 18. Jan 2016, 14:53
Bei mir sind Container immer z.B. so aufgebaut:

Delphi-Quellcode:
type
  TTemperaturList=class(TObject)
  private
    Liste: TObjectList;

    ...
    
  public
    constructor Create;
    destructor Destroy; override;
Von aussen hin kann ich dann gezielt nur die von meiner Klasse definierten Funktionen und Prozeduren aufrufen. Dass innen eine TObjectList oder etwas anderes enthalten ist, soll der Client nicht sehen können.
Michael Justin
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.733 Beiträge
 
Delphi 6 Enterprise
 
#5

AW: TObjectList-Object da, aber beim Zugriff Stack-Overflow

  Alt 18. Jan 2016, 14:57
Ich denke er meint, dass du eine Objektlist in deiner neuen Klasse kapselst. So kann man ganz gut die eventuelle Object-Casterei verbergen.

Edit:Und war sogar selber schneller als ich...

Delphi-Quellcode:
type
  TTemperaturList=class
    ObjectList:TObjectList;
  public
    constructor create;
    function count:integer;
  end;

TTemperaturList.create;
begin
  ObjectList:=TObjectList.create;
end;

TTemperaturList.count:integer;
begin
  Result:=ObjectList.Count;
end;

Andere Bemerkung, wenns erlaubt ist: Was mich an deinem Klassenkonstrukt stört ist was für verschiedene Dinge nicht alles Temp heißen. Da hat ich nämlich auch Probleme deinen QT nachzuvollziehen.
Ralph
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#6

AW: TObjectList-Object da, aber beim Zugriff Stack-Overflow

  Alt 18. Jan 2016, 15:05
Delphi-Quellcode:
type
  TTemperaturList=class(TObjectList)
    function getItem(index: Integer): TTemperatur; virtual;
    procedure setItem(index: Integer; Temperatur: TTemperatur); virtual;
  public
    property Items[index: Integer]: TTemperatur read getItem write setItem; default;
    procedure Insert(index: Integer; Temperatur: TTemperatur); virtual;
    function Add(Temperatur: TTemperatur): Integer; virtual;
    function Remove(Temperatur: TTemperatur): Integer; virtual;
    ...
Die Methoden getItem und setItem brauchen nicht als published declariert werden, eventuell fehlt hier das private. Published wird nicht benötigt ausser man möchte die Klasse über das Delphi DFM Streaming oder klassische RTTI ansprechen.
Michael Justin
  Mit Zitat antworten Zitat
SProske

Registriert seit: 16. Feb 2015
Ort: Halle/S.
116 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#7

AW: TObjectList-Object da, aber beim Zugriff Stack-Overflow

  Alt 18. Jan 2016, 15:12
Da der TE wohl XE4 verwendet, wäre sicher auch die generische Objektliste aus der Unit System.Generics.Collections einen Blick Wert.
Damit könnte man sich die Schreibarbeit für Add/Remove/IndexOf etc. ersparen.
Sebastian
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#8

AW: TObjectList-Object da, aber beim Zugriff Stack-Overflow

  Alt 18. Jan 2016, 15:25
@mjustin:
das Private fehlt tatsächlich. Eigentlich kommen bei mir die Getter und Setter immer in Private, hatte ich lediglich vergessen. (hätte bei dem fehlenden Inherited aber nichts geändert).
Aber ich weiß jetzt was du meinst.

Klar kann man das auch über Generics verwenden. Aber ich habe mich so an meine ObjectList gewöhnt....

Und, zugegeben, der Variablenname Temp ist sicherlich nicht der schlaueste, aber man kann das schon lesen
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: TObjectList-Object da, aber beim Zugriff Stack-Overflow

  Alt 18. Jan 2016, 15:50
Nur so als Tip:

Wenn man Klassen mit Stream-Funktionen ausstattet, dann sollte man auch immer das Interface Delphi-Referenz durchsuchenIStreamPersist an die Klasse heften.

Macht auf jeden Fall das Leben leichter
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
freimatz
Online

Registriert seit: 20. Mai 2010
1.378 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: TObjectList-Object da, aber beim Zugriff Stack-Overflow

  Alt 18. Jan 2016, 16:15
wäre es die Containerklasse nicht von der Klasse TObjectList abzuleiten sondern eine interne (private) TObjecList Instanz zu benutzen. Das entkoppelt die API der TObjectList und sichert den Client-Code besser gegen "versehentliche" Verwendung von TObjectList Methoden ab. Das könnte auch für die konkrete Fehlersuche hilfreich sein.
Aber wenn du mir das noch mal anders erläutern könntest, wäre ich dir sehr dankbar, denn ich weiß im Augenblick nicht was du damit meinst.
Siehe auch:
http://clean-code-developer.de/die-g...heritance_FCoI
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:11 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