AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Kopie eines Item aus der TObjectList

Ein Thema von Kostas · begonnen am 22. Jan 2007 · letzter Beitrag vom 23. Jan 2007
Antwort Antwort
Seite 1 von 2  1 2      
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.095 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

Kopie eines Item aus der TObjectList

  Alt 22. Jan 2007, 01:10
Hallo Zusammen,

die Frage vorab: Wenn ich aus einer TObjectList ein item hole etwa so:
CarPosColl := RawTagesauswertung.Items[i]; bekomme ich dan den Pointer des items oder das item selbst?
Ich hätte gerne eine kopie des items.

Ich habe eine Klasse von TObject die Autos verwaltet.
Dann eine Klasse TCarPosCollection von TObjectList die x Autos verwaltet.
Und zuletzt eine Klasse Tagesauswertung ebenfals aus TObjectList
welche x TCarPosCollection verwaltet.

In einer Schleife lese ich aus der TObjectList "Tagesauswertung" ein paar items und
übergebe diese zum verarbeiten in einer zweiten instanz von Klasse.

So wird die übergabe der items gemacht: CarPosColl := RawTagesauswertung.Items[i]; Wenn ich die Schleife nur ein mal ausführe, funkt alles einwandfrei.

Wenn ich die Schleife ein zweites mal durchführe und dabei vorher
CarPosColl.free aufrufe, bekomme ich eine exception "EAccessViolation".
Ich vermute das ich keine kopie übergebe sonder nur den Pointer des items welches in
meiner Hauptliste steckt. Der Destructor versucht vermutlich das item aus der Haptliste
zu bereinigen.

Habs auch so probiert und bekomme beim free die exception "EPrivilege"
Delphi-Quellcode:
     
CarPosColl := TCarPosCollection.Create;
CarPosColl := RawTagesauswertung.Items[i];

Hat jemand eine Idee?
Hier meine Klassen aus das wesendliche reduziert:
Gruß Kostas


Delphi-Quellcode:
type
  TCarPos = class(TObject)
  private
    FZeitpunkt:TDateTime;
    FCarID:integer;
    Procedure SetZeitpunkt(value :TDateTime);
    function GetZeitpunkt:TDateTime;
    Procedure SetCarID(value :Integer);
    function GetCarID:Integer;
  public
    constructor Create;
    property Zeitpunkt: TDateTime read GetZeitpunkt write SetZeitpunkt;
    property CarID: Integer read GetCarID write SetCarID;
  end;


  TCarPosCollection =Class(TObjectList)
  private
    FZustand:Boolean;
    function Get(Index: Integer): TCarPos;
    procedure SetZustand(value :Boolean);
    function GetZustand:Boolean;
  public
    destructor Destroy; override;
    procedure Add(Item: TCarPos);
    property Items[Index: Integer]: TCarPos read Get;
    property Zustand:Boolean read GetZustand write SetZustand;
  end;

  TTagesauswertung =Class(TObjectList)
  private
    function Get(Index: Integer): TCarPosCollection;
  public
    destructor Destroy; override;
    procedure Add(Item: TCarPosCollection);
    property Items[Index: Integer]: TCarPosCollection read Get;
  end;

destructor TCarPosCollection.Destroy;
var
  i: Integer;
begin
  for i := 0 to self.Count - 1 do
    self.Items[i].Free;
  inherited;
end;

procedure TCarPosCollection.Add(Item: TCarPos);
begin
  inherited Add(Item);
end;

function TCarPosCollection.Get(index: integer):TCarPos;
begin
  result := inherited Get(Index);
end;




destructor TTagesauswertung.Destroy;
var
  i: Integer;
begin
  for i := 0 to self.Count - 1 do
    self.Items[i].Free;
  inherited;
end;

procedure TTagesauswertung.Add(Item: TCarPosCollection);
begin
  inherited Add(Item);
end;

function TTagesauswertung.Get(index: integer):TCarPosCollection;
begin
  result := inherited Get(Index);
end;
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#2

Re: Kopie eines Item aus der TObjectList

  Alt 22. Jan 2007, 01:16
Geb bei der 2. Liste einfach beim Constructor Aufruf ein False mit, dann gibt die TObjectList nicht die Items frei, die in ihr sind. Damit bleiben dann die in der Hauptliste auch weiterhin gültig.

Du bekommst einen Instanzenzeiger. Die TObjectListe verwaltet nur die Instanzenzeiger.
  Mit Zitat antworten Zitat
Benutzerbild von sh17
sh17

Registriert seit: 26. Okt 2005
Ort: Radebeul
1.640 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Kopie eines Item aus der TObjectList

  Alt 22. Jan 2007, 08:49
Du überschreibst bei Deiner TCarPosCollection die Destroy-Methode der TObjectList und gibts alle Items frei. Das ist nicht nötig, das macht TObjectList schon.

Hier mal ein Grundgerüst für KLassen, die von TObjectList erben und somit ein Typecasting überflüssig machen:

Ersetze Name durch Deine Klasse (TCarPos)

Delphi-Quellcode:
NameObjectList = class(TObjectList)
protected
  function GetItem(Index: Integer): Name;
  procedure SetItem(Index: Integer; AItem: Name);
public
  function Add(AItem: Name): Integer;
  function Extract(Item: Name): Name;
  function Remove(AItem: Name): Integer;
  function IndexOf(AItem: Name): Integer;
  procedure Insert(Index: Integer; AItem: Name);
  function First: Name;
  function Last: Name;
  property Items[Index: Integer]: Name read GetItem write SetItem; default;
end;


implementation

{ NameObjectList }

function NameObjectList.Add(AItem: Name): Integer;
begin Result := inherited Add(AItem); end;

function NameObjectList.Extract(Item: Name): Name;
begin Result := Name(inherited Extract(Item)); end;

function NameObjectList.First: Name;
begin if Count = 0 then Result := nil else Result := Name(inherited First); end;

function NameObjectList.GetItem(Index: Integer): Name;
begin Result := Name(inherited Items[Index]); end;

function NameObjectList.IndexOf(AItem: Name): Integer;
begin Result := inherited IndexOf(AItem); end;

procedure NameObjectList.Insert(Index: Integer; AItem: Name);
begin inherited Insert(Index, AItem); end;

function NameObjectList.Last: Name;
begin if Count = 0 then Result := nil else Result := Name(inherited Last); end;

procedure NameObjectList.SetItem(Index: Integer; AItem: Name);
begin inherited Items[Index] := AItem; end;

function NameObjectList.Remove(AItem: Name): Integer;
begin Result := inherited Remove(AItem);end;
Sven Harazim
--
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#4

Re: Kopie eines Item aus der TObjectList

  Alt 22. Jan 2007, 09:33
Zitat von sh17:
Hier mal ein Grundgerüst für KLassen, die von TObjectList erben und somit ein Typecasting überflüssig machen:

Ersetze Name durch Deine Klasse (TCarPos)
Man braucht dafür nur Items[] neu definieren und damit die GetItem/SetItem (oder wie die auch immer genannt werden bei der Implementation), alle anderen brauchen dafür nicht neu implementiert werden.
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.095 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

Re: Kopie eines Item aus der TObjectList

  Alt 22. Jan 2007, 10:01
Danke Muetze1 und sh17,

das ist interessant. Es wird also wirklich keine Kopie des items erzeugt.

Ich benötige unbedingt eine Kopie der items, weil während dem Verarbeiten ich ein
paar Eigenschaften der items verändere. Diese Änderung darf sich jedoch nicht im Master widerspiegeln.

Ich habe leider noch nicht verstanden warum ich die ObjectList nicht leeren darf.

Nochmals kurz beschrieben was ich eigentlich vor habe.
Es gibt eine ObjectList Instanz "TTagesauswertung" die hält alle Daten vor die aus
einem Select aus der DB befühlt wird. Die nenne ich jetzt mal Master.

Jetzt möchte ich die Daten verarbeiten. Ich erzeuge eine weitere, leere Instanz von
"TTagesauswertung". Die nenne ich mal Slave.
Danach gehe ich alle items von Master durch und hole mir ein paar items zum verarbeiten
in die Slave. Dieser Vorgang wird mehrmals wiederholt. Dabei sollen die Master unverändert bleiben.
Wenn ich also fertig bin, rufe ich Slave.free und Slave := TTagesauswertung.Create; auf.

Ihr meint jetzt, der constructor darf die items nicht freigeben.
Sicherlich habt Ihr Recht. Ich verstehe es nur noch nicht warum.
Die items von Master dürfen sicherlich nicht freigegeben werden, aber die items von Slave müssen doch freigegeben werden oder? Wie bereits erwähnt, wird Slave öfters erzeugt, befüllt und wieder zerstört.


Habt Ihr eine Idee?
  Mit Zitat antworten Zitat
Benutzerbild von sh17
sh17

Registriert seit: 26. Okt 2005
Ort: Radebeul
1.640 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Kopie eines Item aus der TObjectList

  Alt 22. Jan 2007, 10:12
TObjectList bietet einen Mechanismus zum Verwalten seiner Items. Ruft man TObjectList.Create(true) auf, gehören die Items dieser Objectlist und sie werden bei ObjectList.clear bzw ObjectList.Free von dieser wieder freigegeben.

Ruft man TObjectList.Create(false) auf, muss man sich selbst um die Freigaben der Items kümmern.

Um eine Kopie eines Items zu bekommen, musst Du dieses Object TCarPos noch z.b. um die funktionen AssignTo und Clone erweitern:

Delphi-Quellcode:

TCarPos
public
  procedure AssignTo(_Dest : TCarPos);
  function Clone : TCarPos;
end;

procedure TCarPos.AssignTo(_Dest : TCarPos);
begin
  _Dest.Zeitpunkt := Zeitpunkt;
  ...
end;

function TCarPos.Clone : TCarPos;
begin
  Result := TCarPos.Create;
  AssignTo(Result);
end;
Dann machst Du einfach

Delphi-Quellcode:

  for i := 0 to master.count-1 do
    slave.add(master[i].clone)
schon hast Du eine Kopie, die Du mit slave.clear wieder löschst.

idealer Weise erweiterst Du Deine Objektlist auch um AssignTo und Clone um sich die Schleife zu sparen
Sven Harazim
--
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.095 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

Re: Kopie eines Item aus der TObjectList

  Alt 22. Jan 2007, 12:21
ich mache mich sofort an die Arbeit.

Tausend Dank und schöne Grüße.

Kostas
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.095 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

Re: Kopie eines Item aus der TObjectList

  Alt 22. Jan 2007, 23:37
Hallo sH17,

es funkt beste Sahne mit dem Clonen.
Hab auch die constructoren aus beiden TObjectList entfernt.
Ein bisschen unwohl ist mir noch bei dieser Sache, weil ich noch nicht
sattelfest bin in OOP. (Ich habe es bis jetzt umgehen können. )
Wenn ich das free der TObjectList aufrufe werden dann auch alle
geklonte items gelöscht?
Ist es eigentlich Möglich memory leaks zu finden?

Hier noch meine drei Klassen. Wenn es Dir möglich währe nochmals drüber zu schauen.

Besten Dank nochmals sH17 und schöne Grüße.


Delphi-Quellcode:
TCarPos = class(TObject)
  private
    FZeitpunkt:TDateTime;
    FCarID:integer;
    Procedure SetZeitpunkt(value :TDateTime);
    function GetZeitpunkt:TDateTime;
    Procedure SetCarID(value :Integer);
    function GetCarID:Integer;
  public
    constructor Create;
    property Zeitpunkt: TDateTime read GetZeitpunkt write SetZeitpunkt;
    property CarID: Integer read GetCarID write SetCarID;
    procedure AssignTo(var Dest : TCarPos);
    function Clone: TCarPos;
  end;

  TCarPosCollection =Class(TObjectList)
  private
    FZustand:Boolean;
    function Get(Index: Integer): TCarPos;
  public
    procedure Add(Item: TCarPos);
    property Items[Index: Integer]: TCarPos read Get;
    procedure AssignTo(var Dest : TCarPosCollection);
    function Clone: TCarPosCollection;
  end;

  TTagesauswertung =Class(TObjectList)
  private
    function Get(Index: Integer): TCarPosCollection;
  public
    procedure Add(Item: TCarPosCollection);
    property Items[Index: Integer]: TCarPosCollection read Get;
  end;


{ TCarPos }
constructor TCarPos.Create;
begin
  FZeitpunkt:=0.0;
  FCarID:=0;
end;

procedure TCarPos.AssignTo(var Dest: TCarPos);
begin
  Dest.FZeitpunkt := FZeitpunkt;
  Dest.FCarID := FCarID;
end;

function TCarPos.Clone: TCarPos;
begin
  result := TCarPos.Create;
  AssignTo(result);
end;


{ TCarPosCollection }
procedure TCarPosCollection.Add(Item: TCarPos);
begin
  inherited Add(Item);
end;

function TCarPosCollection.Get(index: integer):TCarPos;
begin
  result := inherited Get(Index);
end;

procedure TCarPosCollection.AssignTo(var Dest: TCarPosCollection);
var
  i:integer;
begin
  Dest.FZustand := FZustand;

  {kopiere alle items vom typ TCarPos}
  for i := 0 to count-1 do
    Dest.add(items[i].clone);
end;

function TCarPosCollection.Clone: TCarPosCollection;
begin
  result := TCarPosCollection.Create;
  AssignTo(result);

end;


{ TTagesauswertung }
procedure TTagesauswertung.Add(Item: TCarPosCollection);
begin
  inherited Add(Item);
end;

function TTagesauswertung.Get(index: integer):TCarPosCollection;
begin
  result := inherited Get(Index);
end;
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#9

Re: Kopie eines Item aus der TObjectList

  Alt 23. Jan 2007, 00:23
Ich sehe soweit keine Probleme. Sollte alles so klappen. Die Add() Funktion ist nicht unbedingt nötig - ansonsten aber auch nicht falsch.
  Mit Zitat antworten Zitat
Benutzerbild von sh17
sh17

Registriert seit: 26. Okt 2005
Ort: Radebeul
1.640 Beiträge
 
Delphi 11 Alexandria
 
#10

Re: Kopie eines Item aus der TObjectList

  Alt 23. Jan 2007, 08:34
Solange TObjectList.Create(true) aufgerufen wurde, werden bei Free auch die Items freigegeben.

Noch eine Anmerkung zu

Delphi-Quellcode:
procedure TCarPos.AssignTo(var Dest: TCarPos);
begin
  Dest.FZeitpunkt := FZeitpunkt;
  Dest.FCarID := FCarID;
end;
In diesem Fall ist die Verwendung von Dest.FZeitpunkt und Dest.FCarID kein Problem, da die Set-Methoden der Properties Zeitpunkt und CarID auch nix anderes machen. Sollte allerdings in den Set-Methoden weiterer Code stehen, der mit dem Wert vorher noch etwas macht, dann musst Du folgendes aufrufen:

Delphi-Quellcode:
procedure TCarPos.AssignTo(var Dest: TCarPos);
begin
  Dest.Zeitpunkt := Zeitpunkt;
  Dest.CarID := CarID;
end;
Bei

Delphi-Quellcode:
procedure TCarPosCollection.AssignTo(var Dest: TCarPosCollection);
var
  i:integer;
begin
  Dest.FZustand := FZustand;

  {kopiere alle items vom typ TCarPos} 
  for i := 0 to count-1 do
    Dest.add(items[i].clone);
end;
wäre ggf noch ein Dest.Clear zu Beginn sinnvoll.
Sven Harazim
--
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 05: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