Solved

How do I COPY an object?

Posted on 2004-09-22
12
9,512 Views
Last Modified: 2010-10-05
Let's say I have this in Delphi 7:

TMyObject=Class(TObject)
    Field1: String;
end;

var
    Object1,Object2: TMyObject;
begin
    Object1:=TMyObject.Create;
    Object1.Field1:='ONE';
    Object2:=TMyObject.Create;
    Object2:=Object1; (*)
end;

As I understand, the sentence marked with * makes Object2 POINT TO Object1 and I left an space in memory, that was allocated by "Object2:=TMyObject.Create;", that can not be referenced.

A. Is this correct?

B. What I really need is to have a COPY in memory of Object1 called Object2 so that they are totally independent from each other. How can I accomplish this?

Thanks a lot in advance.


Regards AJ.
0
Comment
Question by:ajgonzalezm
12 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 12125968
try this change

TMyObject=Class(TPersistent)  //persitent class introduces the assign method
    Field1: String;
end;

var
    Object1,Object2: TMyObject;
begin
    Object1:=TMyObject.Create;
    Object1.Field1:='ONE';
    Object2:=TMyObject.Create;
    Object2.Assign(Object1); //use assign for copy properties, maybe u must add a property
end;

not tested, just from head

meikl ;-)
0
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 12126266
the Assign method is the answer as kretzchmar said

this will do

Object2.Assign(Object1);
0
 
LVL 2

Expert Comment

by:__alex
ID: 12130505
consider an object with fields that are objects;

TYourClass = class
private
  anotherObject: TAnotherClass;
end;

If you don't want to derive from TPersistent (I guess the Assign method needs some additional information: published properties..., not sure about that) you can write your own Assign method.

TYourClass = class
public
  procedure Assign(const source: TYourClass);
private
  s: string;
  anotherObject: TAnotherClass;
end;

procedure TYourClass.Assign(const source: TYourClass);
begin
  // Copy all data
  s := source.s;
  anotherObject.Assign(source.anotherObject);   // You have to imlement TAnotherClass.Assign
end;

Usage:

var
    Object1,Object2: TYourClass ;
begin
    Object1:=TYourClass.Create;
    Object2:=TYourClass.Create;
    Object2.Assign(Object1);
end;
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 3

Accepted Solution

by:
jpedef earned 50 total points
ID: 12131766
Assign doesn't work unless you write somekind of copying procedure.
Compile TMyObject with TypeInfo {$M+} or derive it from TPersistent.

Then you can use typeinfo to copy published properties from one object to another.

procedure CopyObject(Source, Dest: TMyObject);
var
  TypInfo: PTypeInfo;                                                        
  PropList: TPropList;
  PropCount, i: integer;
  Value: variant;
begin
  TypInfo := Source.ClassInfo;
  PropCount := GetPropList(TypInfo, tkAny, @PropList);
  for i := 0 to PropCount - 1 do
  begin
    Value := GetPropValue (Source, PropList [i]^.Name);
    SetPropValue (Dest, PropList [i]^.Name, Value);
  end;
end;
0
 
LVL 6

Expert Comment

by:pritaeas
ID: 12132327
That works for published properties, but that doesn't work if you have an array property. Or any other custom class as property for that matter. Assign() is the way to go.
0
 
LVL 3

Expert Comment

by:jpedef
ID: 12132610
Its not the name of the procedure.
Assign doesn't solve anything and you must anyway override Assign (or AssignTo) procedure if you want to use it with your custom object.

That typeinfo example could also be in overridden Assign or AssignTo procedure (I've used that many times).
And yes, you can only copy published properties with typeinfo, but if you want to copy anything else (private, public ...) you need to write your own copy procedure (Assign or not).

I must admit that this typeinfo example is slow, becase it uses variants insterad of "real" types. If efficiency comes to way you should also check typekind of property and use different methods for different types instead. You should also check if property setter is present (readonly properties) and that you really can copy that specific kind of property (arrays, classes).
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 12132764
from my point of view its enough to derive it from TPersistent
(just not sure if a published property is needed),
but in case of need the type looks like

TMyObject=Class(TPersistent)  
    Field1: String;
published
  property F1 : String read Field1 write Field1;
end;

after this assign should work properly

meikl ;-)

0
 
LVL 3

Expert Comment

by:jpedef
ID: 12140229
You should take a look of TPersistent's Assign implementation.
Or just try it. Assign raises error "Cannot assign a TMyObject to a TMyObject'.
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 12140302
well,
i have currently no delphi on hand,
but i will do a test later,
guess the assign method is virtual at tpersistent

in this case you are correct, jpedef,
and it should better derived from TComponent,
or with your suggestion

meikl ;-)
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question