Solved

How do I COPY an object?

Posted on 2004-09-22
12
9,601 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Secure Your Active Directory - April 20, 2017

Active Directory plays a critical role in your company’s IT infrastructure and keeping it secure in today’s hacker-infested world is a must.
Microsoft published 300+ pages of guidance, but who has the time, money, and resources to implement? Register now to find an easier way.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Tviruailstringtree sort multi columns on header click 1 85
Delphi...Split view - idea? 1 114
update joined tables 2 62
how can i delete one control based on its tagstring ? 6 36
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

749 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