Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Kopie eines Item aus der TObjectList (https://www.delphipraxis.net/84800-kopie-eines-item-aus-der-tobjectlist.html)

Kostas 23. Jan 2007 08:14

Re: Kopie eines Item aus der TObjectList
 
Zitat:

Zitat von Muetze1
Ich sehe soweit keine Probleme. Sollte alles so klappen. Die Add() Funktion ist nicht unbedingt nötig - ansonsten aber auch nicht falsch.

Hallo Muetze1,

habe es so belassen um beim add nicht typecasten zu müssen.
Entfernt, ist es dann wie generics bei c#

Gruß Kostas

Sidorion 23. Jan 2007 08:26

Re: Kopie eines Item aus der TObjectList
 
Zitat:

Zitat von sh17
Delphi-Quellcode:
procedure NameObjectList.SetItem(Index: Integer; AItem: Name);
begin inherited Items[Index] := AItem; end;

Grober Schnitzer! Beim Aufruf der geerbten Property (TObjectList.Items) wird die Setter-Methode gesucht. Das wäre TObjectList.SetItem. Da diese aber virtuell ist, wird geschaut, ob sie überschrieben ist. Da dies der Fall ist, wird die geerbte Methode gerufen und das wäre NameOjectList.SetItem und das gibt ne Endlosschleife.

Um zu erzwingen, dass die geerbte Methode gerufen wird musst Du direkt die Methode rufen, also:
Delphi-Quellcode:
procedure NameObjectList.SetItem(Index: Integer; AItem: Name);
begin inherited SetItem(Index,AItem); end;
das gleiche gilt für die getter-Methode.

p.s.: Das ist einer der wenigen Fälle, wo man nicht die Property, sondern die dazugehörigen Getter/Setter aufruft, ansonsten hast Du Recht mit der bevorzugten Verwendung der Property.

Muetze1 23. Jan 2007 08:27

Re: Kopie eines Item aus der TObjectList
 
Zitat:

Zitat von Kostas
habe es so belassen um beim add nicht typecasten zu müssen.

Hä? Wieso typecast? Ich versteh nix. Wenn du Add() nicht veränderst, dann nimmt er Parameter vom Typ TObject. Da deine Klasse von TObject abgeleitet ist, akzeptiert er diese ohne Probleme. Du musst typecasten, wenn dein Add() einen höhren Typ hat. Also in deiner Methode musst du typecasten, nicht umgekehrt...

@Sidorion: Probier bitte deine Behauptung mal aus. Die GetItem() und SetItem() sind privat in der TObjectList und nicht virtual. Damit werden die SetItem() und GetItem() von TObjectList versteckt und sind nicht mehr aufrufbar. Somit kannst du schlecht ein Inherited SetItem() aufrufen. Der hier gepostete Weg ist der richtige. Mit dem Inherited Items[] greift er auf die Items der TObjectList zu und diese nutzen ihre (in der Ableitung versteckten) GetItem() und SetItem() Methoden. Die TObjectList könnte die GetItem() und SetItem() von der Ableitung nur aufrufen, wenn diese überschrieben wurden - und das sind sie nicht bzw. können sie nicht.

Probier dein geschriebenes bitter selber aus!

/EDIT: Nachgeschaut: SetItem() und GetItem() sind protected und nicht virtuell. Damit können Sie zwar aufgerufen werden mit dem Inherited, aber die o.g. Schleife kann nicht eintreten. Der Inherited Items[] Zugriff greift auf die GetItem() und SetItem() der TObjectList zu. Diese beiden Methoden werden nur versteckt, nicht aber überschrieben und somit gibt es keine Schleife. Eine Schleife würde es beim Zugriff auf Items[] ohne Inherited geben.

Kostas 23. Jan 2007 08:29

Re: Kopie eines Item aus der TObjectList
 
Zitat:

Zitat von sh17
Solange TObjectList.Create(true) aufgerufen wurde, werden bei Free auch die Items freigegeben.

Das habe ich so gemacht, aber jetzt erst verstanden. :-)


Zitat:

Zitat von sh17
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;

Ah, schön langsam Dämmert, ich dachte nur die Privaten Felder dürfen geclont werden.
Ich werde sofort auf Properties umstellen.

Zitat:

Zitat von sh17

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.

Dest.Clear habs eingebaut.

Es funkt alles einwandfrei.

Super Leute besten Dank und schöne Grüße.

Kostas

Sidorion 23. Jan 2007 10:34

Re: Kopie eines Item aus der TObjectList
 
@Muetze1: Hmmm. nicht virtuell... dann vergiss meine Behauptung mit der Schleife (in diesem Fall). Jedoch ist die Aussage an sich nicht falsch, da sobald ein Setter/Getter virtuell ist kommt es eben zu diesem Problem (hab ich schon erlebt). Darum stimmt die Aussage 'Inherited SetItem' zu rufen immernoch, weil niemand kann garantieren, dass TObjectList.SetItem für immer statisch ist :wink: Den 'groben Schnitzer' nehme ich also offiziell zurück :mrgreen:

Muetze1 23. Jan 2007 11:15

Re: Kopie eines Item aus der TObjectList
 
Nö, weil wenn GetItem() SetItem virtuell sind, dann würdest du diese immernoch nicht überschreiben. Statt dessen würdest du eine Warnung vom Compiler bekommen (verdeckt virtuelle Methode aus der Basisklasse TObjectList, etc) aber trotzdem würdest du nichts überschreiben. Die alten werden verdeckt und du implementierst ganz neue. Dadurch würde inherited immerncoh die Originalen Methoden von TObjectList aufrufen und nicht die eigenen.
Erst wenn du in deiner Ableitung der Warnung die Grundlage entziehst und die virtuellen Methoden richtig überschreibst mit Override, dann würde dein geschildertes Szenario eintreten. So lange du aber die Warnung stehen lässt oder aber mit ReIntroduce diese unterdrückst, hast du keine Probleme mit dem Inherited SetItem() / GetItem().


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