Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Objekt duplizieren? (https://www.delphipraxis.net/109711-objekt-duplizieren.html)

PeterPanino 6. Mär 2008 10:21


Objekt duplizieren?
 
Gibt es eine Methode, mit der man ein Objekt duplizieren - also eine neue identische Instanz eines existierenden Objektes erzeugen - kann?

Bernhard Geyer 6. Mär 2008 10:24

Re: Objekt duplizieren?
 
Jein. Bei Basisklassen ja, bei eigenen mußt du die Assign-Methode überschreiben und selbst die Logik für das Duplizieren implementieren.

PeterPanino 6. Mär 2008 10:26

Re: Objekt duplizieren?
 
Schade. Wäre zu bequem gewesen!

Bernhard Geyer 6. Mär 2008 10:27

Re: Objekt duplizieren?
 
Zitat:

Zitat von PeterPanino
Schade. Wäre zu bequem gewesen!

Jedoch kann der Compiler nicht wissen wie er jedes Element behandeln muss. Kopie als speicherbereich-Kopie? Ebenfalls Assign Aufrufen. Evtl. irgendwelche Create/...-Aufrufe für Ressourcen?

sirius 6. Mär 2008 10:36

Re: Objekt duplizieren?
 
Da ist die Frage, was du mit duplizieren meinst. Also was ist mit weiteren Objekten innerhalb deines Objektes?
Hier ist eine Möglichkeit für eine von TPersistent abgleitete Klasse, alle published Properties zu "kopieren". Aber wie gesagt, beispielsweie bei internen Klassen wird nur der Objektzeiger kopiert.

PeterPanino 6. Mär 2008 10:39

Re: Objekt duplizieren?
 
Es ist eine eigene Klasse, von TObject abgeleitet.

Aber nur so aus Interesse: Gibt es eigentlich objektorientierte Hochsprachen, bei denen das Duplizieren eines Objektes einer eigenen Klasse möglich ist? Die Basisklasse TObject müsste dann wohl so aufgebaut sein, dass der Compiler jederzeit die Elemente einer beliebigen Klasse erfahren und somit diese dann der neuen Instanz zuweisen kann.

phXql 6. Mär 2008 10:46

Re: Objekt duplizieren?
 
C# und Java können sowas. Machen aber nur eine flache Kopie. Denke das geht mithilfe von Reflection.

sirius 6. Mär 2008 10:58

Re: Objekt duplizieren?
 
Du hast so ziemlich den Nagel auf den Kopf getroffen.
Es geht halt nur wenn sogenannte RunTime-Type-Informations vorhanden sind (kurz RTTI). Die sind in Teilen vorhanden, soweit sie halt gebraucht werden. Zum Beispiel muss in einem Record oder in einer Klasse stehen, wo ein String ist, damit er beim Auflösen der Struktur auch gelöscht werden kann. Und das steht immer da. Zusätzlich kann man den Compiler dazu bewegen in Klassen Informationen über alle published-Deklarationen zu hinterlegen (bis hin zu den Parametern von Methoden). Genau das ist auch der einzige Unterschied zwischen TObject und TPersistent. (Wobei man das mit einem Compilerschalter {$M} auch für eine von TObject abgleitete Klasse machen kann) Damit kann man dann eine komplette Kopierroutine schreiben (wie in dem Link).

Ich sehe grade, dass die verlinkte Methode das kopieren von Klassen derzeit komplett verweigert (also nicht diese Methode aber die Funktion aus der unit TypInfo). Ist ja auch klar, denn nach welchem Schema soll die Klasse dann kopiert werden?

Man kann sich unter zu Hilfenahme dieser Informationen eine Basisklasse schreiben, welche den Kopiervorgang implementiert. Und dann kann man alle Klassen, welche von dieser Klasse abgeleitet sind kopieren. Die VCL hat ja im Prinip für sich auch ein paar Routinen dazu. Aber etwas fertiges, allgemeingültiges kann man unter Delphi nicht schreiben.

Zu anderen Sprachen, kannst du mal hier lesen.

Muetze1 6. Mär 2008 16:31

Re: Objekt duplizieren?
 
Zitat:

Zitat von phXql
C# und Java können sowas. Machen aber nur eine flache Kopie. Denke das geht mithilfe von Reflection.

Zählt der CopyConstructor von C++ nicht dazu?

phXql 6. Mär 2008 16:55

Re: Objekt duplizieren?
 
Hm, wenn der CopyCtor in C++ vernünftig mit vererbung umgehen kann, dann zählt er dazu, ja :)

PeterPanino 8. Mär 2008 16:41

Re: Objekt duplizieren?
 
Zitat:

Zitat von sirius
Und dann kann man alle Klassen, welche von dieser Klasse abgeleitet sind kopieren.

Ich möchte ja keine Haare spalten, aber müsste es semantisch korrekt nicht heißen: "Und dann kann man alle Objekte, welche von dieser Klasse abgeleitet sind kopieren."? Eine Klasse ist ja nur die Abstraktion eines Objektes, während ein Objekt eine Instanz einer Klasse darstellt. Und wenn man nun eine Klasse mit einer Henne vergleicht, ist das Ei dann das Objekt? Und war der Urknall eine Klasse oder Objekt?

Ansonsten vielen Dank für deine Ausführungen.

Elvis 8. Mär 2008 16:53

Re: Objekt duplizieren?
 
Zitat:

Zitat von phXql
C# und Java können sowas. Machen aber nur eine flache Kopie. Denke das geht mithilfe von Reflection.

:shock: *hust*
Delphi-Quellcode:
[Extension]
class method Cloner.CreateDeepClone<T>(instance : T) : T;
begin
  var bf := new BinaryFormatter();

  using s := new MemoryStream() do
  begin
    bf.Serialize(s, instance);
    s.Position := 0;
    exit T(bf.Deserialize(s));
  end;
end;

....

begin
  var a := new MyClass(SomeProperty := 'Abc');
  var b := a. CreateDeepClone();

  b.SomeProperty := b.SomeProperty + 'def';
  ...
end;
In Delphi geht sowas nicht.
Delphis RTTI ist eher das was der Compiler hat liegen lassen, für die meisten Sachen reicht das bissel einfach nicht.
Eine flache Kopie ließe sich anfertigen, indem man den Record hinter dem Objekt kopiert.
Aber das wäre dann nur ein flache Kopie. Sämtliche Referenzen würden immer noch auf die gleichen Bereiche zeigen.

phXql 8. Mär 2008 22:27

Re: Objekt duplizieren?
 
Ich meinte auch von Haus aus. Selbst basteln kann man sich fast immer was ;)

Und bei deiner Methode muss die Klasse und alle Klassen die sonst wie in dem Objektgraphen hängen das Attribut SerializableAttribute haben, sonst mag der BinaryFormatter nich mehr.

// Oder war dein Hust auf mein Schreiben von C# anstatt .NET bezogen? :)

Elvis 8. Mär 2008 22:37

Re: Objekt duplizieren?
 
Zitat:

Zitat von phXql
Ich meinte auch von Haus aus. Selbst basteln kann man sich fast immer was ;)

Und bei deiner Methode muss die Klasse und alle Properties das Attribut SerializableAttribute haben, sonst mag der BinaryFormatter nich mehr.

Ieh ist das Offtopic, aber nunja...
Wenn in .Net eine Klasse IClonable implementiert, dann entspricht das dem was man von einem AssignTo bei TPersistent "erwarten" würde: Ein komplett eigenständiger Klon. Nur halt ohne dich an einen Vorfahren zu fesseln.
Was ich oben stehen habe ist eine Extension method, mit der man jede Klasse kopieren kann, da der Inhalt der Felder rekursiv und inklusive zirkulärer Referenzen kopiert wird.

phXql 8. Mär 2008 22:57

Re: Objekt duplizieren?
 
Jo, Clone() von IClonable macht eine tiefe Kopie, MemberwiseClone() eine flache. Und was bringt mir dann deine Methode?

Elvis 9. Mär 2008 06:18

Re: Objekt duplizieren?
 
Zitat:

Zitat von phXql
Jo, Clone() von IClonable macht eine tiefe Kopie, MemberwiseClone() eine flache. Und was bringt mir dann deine Methode?

"Clone" gibbet nicht immer ;-)

phXql 9. Mär 2008 09:06

Re: Objekt duplizieren?
 
Und das Serializable-Attribut auf der Klasse auch nicht ;)

spaxxn 2. Apr 2008 13:44

Re: Objekt duplizieren?
 
Delphi-Quellcode:
procedure CopyComponent(AComponentChild, ACopyOfComponentChild: : TComponentChild);
var
  locMS                        : TMemoryStream;
begin
  locMS := nil;
  try
    locMS := TMemoryStream.Create;
    try
      locMS.WriteComponent(AComponentChild);
      locMS.Position := 0;
      locMS.ReadComponent(ACopyOfComponentChild);
    except
      raise Exception.Create('Fehler beim Kopieren des Objektes');
    end;
  finally
    locMS.Free;
  end;
end;
Es wird dabei davon ausgegangen, das beide übergebenen Parameter bereits instanziert sind.

Vielleicht kannst was damit anfangen.


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