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 2 von 2     12   
Kostas

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

Re: Kopie eines Item aus der TObjectList

  Alt 23. Jan 2007, 08:14
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
  Mit Zitat antworten Zitat
Sidorion

Registriert seit: 23. Jun 2005
403 Beiträge
 
#12

Re: Kopie eines Item aus der TObjectList

  Alt 23. Jan 2007, 08:26
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.
Manchmal sehen Dinge, die wie Dinge aussehen wollen mehr wie Dinge aus, als Dinge
<Esmerelda Wetterwachs>
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#13

Re: Kopie eines Item aus der TObjectList

  Alt 23. Jan 2007, 08:27
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.
  Mit Zitat antworten Zitat
Kostas

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

Re: Kopie eines Item aus der TObjectList

  Alt 23. Jan 2007, 08:29
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 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 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
  Mit Zitat antworten Zitat
Sidorion

Registriert seit: 23. Jun 2005
403 Beiträge
 
#15

Re: Kopie eines Item aus der TObjectList

  Alt 23. Jan 2007, 10:34
@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 Den 'groben Schnitzer' nehme ich also offiziell zurück
Manchmal sehen Dinge, die wie Dinge aussehen wollen mehr wie Dinge aus, als Dinge
<Esmerelda Wetterwachs>
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#16

Re: Kopie eines Item aus der TObjectList

  Alt 23. Jan 2007, 11:15
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().
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 22:37 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