Delphi prototype sample

I was wondering if there is anything in RTTI Delphi that will do the same as MemberwiseClone in C # for a simple implementation of the prototype template. I saw some Delphi implementations of this template, where a new object is created (TMyObject.Create), and the properties assigned by the values โ€‹โ€‹from the prototype object. Maybe I'm wrong, but I donโ€™t see the benefits of the template if we create objects in the same basic way.

Thanks.

+4
source share
5 answers

Nothing is built there that will perform a deep clone for you. I'm sure you could write a deep clone based on the new RTTI, but I expect this to be a non-trivial job.

If you were dealing with fairly simple types, this would work well, but you could easily run into serious problems. For example, from the top of the head:

  • Some groups of objects must be created in a specific order.
  • Some class members should not be cloned, for example. reference counting. How do you recognize those with RTTI?
  • How do you deal with single player games?
  • What about any external links you need to configure? Suppose you clone an object that is usually created using factory. If this factory contains a link to the created objects, then your design may break behind it.

You can implement your prototype template by specifying the base Clone() method, which uses RTTI for simple types, and then you must override it for something more complex. Personally, I would inherit from TPersistent and make my Assign based Clone() method.

+6
source

The Object.MemberwiseClone Method makes a copy of a shallow object according to several very simple rules and takes advantage of the .NET garbage collector.

  • Links are simply copied. This includes strings and links to any object .
  • Value types copied (identical clones made).

The value types part can be easily duplicated using Delphi. Duplicating the reference type behavior with Delphi, while technically easy, will not provide the expected result: it is expected that Delphi code will be .free the objects it creates and uses the owner-owned paradigm to make sure that this happens. A regular template is free objects created by the owner object from the destructor. If you make a copy of the shalow object, this leads to an error. Here is an example:

  • Object A owns a reference to object B.
  • We create object C as a shallow copy of object A. Object C now contains a reference to object B.
  • We free the object A: A.Free;
  • We free the object B: B.Free; - this automatically calls B.Free , but unfortunately B is already released when we released A!

We could try deep-copy , as David suggests, but this creates some equally complex problems:

  • Not all objects must be copied, for example, because they encapsulate links to real resources (for example: TFileStream).
  • Some other objects cannot be deeply copied, as they are in Essance Singletons. And there is no universal way to say: "This object is a singleton, make a plain copy, do not make a deep copy." Example: will we copy Application ?
  • If you make a deep copy, you may have circular links, you need to take care of this. This is not trivial, and you start a copy from an element in the collection, you can return to the parent element of your collection, that is: not exactly the expected result.
  • Indiscriminate deep copying can lead to unexpected amounts of memory and lead to unexpected memory leaks. Remember the sample collection โ†’ item โ†’ copy item again, where you get a copy of โ€œitemโ€, but the entire COLLECTION collection was copied due to unexpected backlinks.

Combining all this, we can come to one conclusion: we cannot have a general purpose, the equivalent of Delphi MemberwiseClone . We can have a partial appearance for simpler objects with simple interactions, but this is not so attractive!

+9
source

Theres a way to perform deep copying (cloning) of an object in Delphi. It works for the latest versions of Delphi (2010 and above). See the code below ... its actually quite simple, and you don't need external libraries. You can find more information here: http://www.yanniel.info/2012/02/deep-copy-clone-object-delphi.html

 function DeepCopy(aValue: TObject): TObject; var MarshalObj: TJSONMarshal; UnMarshalObj: TJSONUnMarshal; JSONValue: TJSONValue; begin Result:= nil; MarshalObj := TJSONMarshal.Create; UnMarshalObj := TJSONUnMarshal.Create; try JSONValue := MarshalObj.Marshal(aValue); try if Assigned(JSONValue) then Result:= UnMarshalObj.Unmarshal(JSONValue); finally JSONValue.Free; end; finally MarshalObj.Free; UnMarshalObj.Free; end; end; 
+3
source

I think you are looking for something similar to this: http://code.google.com/p/delphilhlplib/source/browse/trunk/Library/src/Extensions/DeHL.Cloning.pas

It will only work on D2010 and above (requires advanced RTTI).

+1
source

I posted a few general component cloning that may be useful, although this is not the equivalent of MemberWiseClone . I think it works in Delphi back in D5, and I'm sure it works in D2007.

+1
source

Source: https://habr.com/ru/post/1345856/


All Articles