Solved

How do I COPY an object?

Posted on 2004-09-22
12
9,314 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
 
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
As a trusted technology advisor to your customers you are likely getting the daily question of, ‘should I put this in the cloud?’ As customer demands for cloud services increases, companies will see a shift from traditional buying patterns to new…

920 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now