AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Objekt in Array kopieren und anschließend freigeben
Thema durchsuchen
Ansicht
Themen-Optionen

Objekt in Array kopieren und anschließend freigeben

Ein Thema von blackdrake · begonnen am 30. Aug 2008 · letzter Beitrag vom 1. Sep 2008
Antwort Antwort
Seite 3 von 3     123   
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#21

Re: Objekt in Array kopieren und anschließend freigeben

  Alt 31. Aug 2008, 14:04
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:
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;
Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#22

Re: Objekt in Array kopieren und anschließend freigeben

  Alt 1. Sep 2008, 07:42
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?
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#23

Re: Objekt in Array kopieren und anschließend freigeben

  Alt 1. Sep 2008, 17:09
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:
type
  TExtendedSubmission = class(TSubmission)
  public
    Extension: string;
    DateTime: string;
    Author: string;
    procedure Assign(Source: TPersistent); override;
  end;
Dann werden alle Elemente von TSubmission mitgenommen. Das ist sehr gut. Aber bei der TExtendedSubmission.Assign() Methode geht das ganze ja wieder zu bruch.

Delphi-Quellcode:
{ 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;
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.

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
Daniel Marschall
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#24

Re: Objekt in Array kopieren und anschließend freigeben

  Alt 1. Sep 2008, 17:40
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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#25

Re: Objekt in Array kopieren und anschließend freigeben

  Alt 1. Sep 2008, 17:50
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"

Delphi-Quellcode:
{ 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;
Folgender Testcode erzeugt auch das gewünschte Ergebnis:

Delphi-Quellcode:
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;
Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


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