![]() |
Re: Objekt in Array kopieren und anschließend freigeben
Hallo.
Vielen Dank für die Hinweise. Ich habe meine Objektliste bei Add() und Insert() so modifiziert, sodass sie die Objekte dupliziert anstelle nur zu referenzieren. Ich muss mich jetzt beim Umgang mit Add() also nicht mehr explizit um die Duplizierung kümmern. Außerdem kann ich meine Objekte dann sofort freigeben, was bei den Ressourcenschutzblöcken für Übersichtlichkeit sorgt. Ich hoffe, dass mein Code nun professioneller in Sachen OOP geworden ist.
Delphi-Quellcode:
Gruß
type
TSubmission = class(TPersistent) public Tags: string; Rating: string; Score: integer; PictureNumber: integer; MD5: string; procedure Assign(Source: TPersistent); override; end; TSubmissionCollection = class(TObjectList) protected function getItem(Index: Integer): TSubmission; virtual; procedure setItem(Index: Integer; Objekt: TSubmission); virtual; public function Add(Objekt: TSubmission): Integer; virtual; function Remove(Objekt: TSubmission): Integer; virtual; function IndexOf(Objekt: TSubmission): Integer; virtual; procedure Insert(Index: Integer; Objekt: TSubmission); virtual; function First: TSubmission; virtual; function Last: TSubmission; virtual; property Items[index: Integer]: TSubmission read getItem write setItem; default; end; { TSubmission } procedure TSubmission.Assign(Source: TPersistent); begin if Source is TSubmission then begin Tags := TSubmission(Source).Tags; Rating := TSubmission(Source).Rating; Score := TSubmission(Source).Score; PictureNumber := TSubmission(Source).PictureNumber; MD5 := TSubmission(Source).MD5; end else inherited; end; { TSubmissionCollection } function TSubmissionCollection.getItem(Index: Integer): TSubmission; begin Result := TSubmission(inherited Items[Index]); end; procedure TSubmissionCollection.setItem(Index: Integer; Objekt: TSubmission); begin inherited Items[Index] := Objekt; end; function TSubmissionCollection.Add(Objekt: TSubmission): Integer; var duplikat: TSubmission; begin duplikat := TSubmission.Create; duplikat.Assign(Objekt); Result := inherited Add(duplikat); end; function TSubmissionCollection.First: TSubmission; begin Result := TSubmission(inherited First()); end; function TSubmissionCollection.IndexOf(Objekt: TSubmission): Integer; begin Result := inherited IndexOf(Objekt); end; procedure TSubmissionCollection.Insert(Index: Integer; Objekt: TSubmission); var duplikat: TSubmission; begin duplikat := TSubmission.Create; duplikat.Assign(Objekt); inherited Insert(Index, duplikat); end; function TSubmissionCollection.Last: TSubmission; begin Result := TSubmission(inherited Last()); end; function TSubmissionCollection.Remove(Objekt: TSubmission): Integer; begin Result := inherited Remove(Objekt); end; { Anwendungsbeispiel } function Filtere(Input: TSubmissionCollection): TSubmissionCollection; var i: integer; begin result := TSubmissionCollection.Create; for i := 0 to Input.Count - 1 do begin if odd(i) then begin result.Add(Input.Items[i]); end; end; end; procedure TForm1.FormCreate(Sender: TObject); var x, y: TSubmissionCollection; sub: TSubmission; i: integer; begin x := TSubmissionCollection.Create; try for i := 0 to 100 do begin sub := TSubmission.Create; try sub.MD5 := 'Test'+IntToStr(i); x.Add(sub); finally sub.Free; end; end; y := Filtere(x); try finally y.Free; end; finally x.Free; end; end; blackdrake |
Re: Objekt in Array kopieren und anschließend freigeben
Mal eine andere Frage: Warum brauchst du eine Kopie einer Liste, wenn du die Ausgangsliste direkt nach dem Kopieren entfernen willst? Wäre es nicht geschickter die bestehende Liste weiter zu verwenden?
|
Re: Objekt in Array kopieren und anschließend freigeben
Hallo.
Bei meinem verwendeten Code geht die Liste mit allen Submissions in 2 Filterfunktionen, die wiederum 2 Listen erstellen. Die Originalliste wird auch noch verwendet, nachdem sie in 2 Unterlisten aufgeteilt wurde. Aber mal zu einem anderen Problem - Bei meiner Arbeit mit den TPersistent-Nachkommen und dem Assign()-Befehl habe ich wieder einen Nachteil entdeckt, der mir etwas zu wider ist: Ich bin ja von den records+arrays weggegangen, da man einen record nicht ableiten kann. Es sei jetzt eine neue Klasse von TSubmission abgeleitet:
Delphi-Quellcode:
Dann werden alle Elemente von TSubmission mitgenommen. Das ist sehr gut. Aber bei der TExtendedSubmission.Assign() Methode geht das ganze ja wieder zu bruch.
type
TExtendedSubmission = class(TSubmission) public Extension: string; DateTime: string; Author: string; procedure Assign(Source: TPersistent); override; end;
Delphi-Quellcode:
In dieser Assign()-Methode MUSS ich alle Elemente der TSubmission (Tags, Rating, Score, PictureNumber und MD5) explizit in den Code mit einbinden. Und ich sehe keine Lösung dafür.
{ TExtendedSubmission }
procedure TExtendedSubmission.Assign(Source: TPersistent); begin if Source is TExtendedSubmission then begin { Hartcoding von TSubmission } // TSubmission würde durch diesen Code zur Unveränderlichkeit gezwungen werden, // da bei einer Veränderung alle Nachkommen ungültig werden würden Tags := TExtendedSubmission(Source).Tags; Rating := TExtendedSubmission(Source).Rating; Score := TExtendedSubmission(Source).Score; PictureNumber := TExtendedSubmission(Source).PictureNumber; MD5 := TExtendedSubmission(Source).MD5; { Nun die neuen Methoden der eigenen Klasse } Extension := TExtendedSubmission(Source).Extension; DateTime := TExtendedSubmission(Source).DateTime; Author := TExtendedSubmission(Source).Author; end else inherited; end; Nehmen wir mal an, ich würde TSubmission verändern/erweitern. TExtendedSubmission würde sich automatisch mit erweitern. Das ist der große Vorteil gegenüber den records, die ja leichter zu handhaben sind. Aber die Methode TExtendedSubmission.Assign() bleibt weiterhin unaktuell. Sie muss explizit angepasst werden, wenn ich TSubmission verändere. Allgemein müsste ich also ALLE Nachkommen in der Assign()-Methode separat umschreiben, wenn ich etwas am Grundtyp TSubmission ändere - sollte die OOP das nicht irgendwie verhindern? // Ich habe bezüglich der Problematik das Thema nochmal als offene Frage gesetzt. Gruß blackdrake |
Re: Objekt in Array kopieren und anschließend freigeben
Nimm das Inherited nicht in den Else-Zweig. In TSubmission.Assign ergibt die is-Abfrage ja immer noch True, sodass die alten Felder auch kopiert werden.
|
Re: Objekt in Array kopieren und anschließend freigeben
Hallo.
Vielen Dank für deine Antwort! Jetzt habe ich genau das, was ich wollte und die Klasse TSubmission kann nun beliebig verändert werden, ohne dass die Nachkommen darunter "leiden" :-D
Delphi-Quellcode:
Folgender Testcode erzeugt auch das gewünschte Ergebnis:
{ TSubmission }
procedure TSubmission.Assign(Source: TPersistent); begin if Source is TSubmission then begin Tags := TSubmission(Source).Tags; Rating := TSubmission(Source).Rating; Score := TSubmission(Source).Score; PictureNumber := TSubmission(Source).PictureNumber; MD5 := TSubmission(Source).MD5; end else inherited; end; { TExtendedSubmission } procedure TExtendedSubmission.Assign(Source: TPersistent); begin if Source is TExtendedSubmission then begin Extension := TExtendedSubmission(Source).Extension; DateTime := TExtendedSubmission(Source).DateTime; Author := TExtendedSubmission(Source).Author; end; inherited; end;
Delphi-Quellcode:
Gruß
procedure TMainForm.Button1Click(Sender: TObject);
var x, y: TExtendedSubmission; begin x := TExtendedSubmission.Create; try x.MD5 := 'Test'; y := TExtendedSubmission.Create; try y.Assign(x); showmessage(y.MD5); // = "Test" finally y.Free; end; finally x.Free end; end; blackdrake |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz