Reputation: 855
this is my sample code :
type
PData = ^TData;
TData = record
str : string;
strlist : TStringList;
end;
var
P1 : PData;
P2 : PData;
P3 : PData;
P4 : PData;
begin
New(P1);
New(P2);
P1.str := 'string';
// copy
P2^ := P1^;
P2.str := P2.str + '_copy';
Memo1.Lines.Add('This is P1:' + P1.str); //This is P1:string
Memo1.Lines.Add('This is P2:' + P2.str); //This is P2:string_copy
// so change P2'Data didn't change P1's Data
// but this :
New(P3);
New(P4);
P3.str := 'string';
P3.strlist := TStringList.Create;
P3.strlist.Add('one line');
// copy
P4^ := P3^;
// just add P4's data
P4.strlist.Add('two line');
Memo1.Lines.Add('P3''s Data:' + IntToStr(P3.strlist.Count));
Memo1.Lines.Add(P3.strlist.Text);
Memo1.Lines.Add('P4''s Data:' + IntToStr(P4.strlist.Count));
Memo1.Lines.Add(P4.strlist.Text);
{
P3's Data:2
one line
two line
P4's Data:2
one line
two line
}
end;
why when copy point data with a class
, it will change raw data , but when data is string
use P1^ := P2^
copy point data does not change raw data.
Upvotes: 4
Views: 207
Reputation: 1287
String is somewhat of a Delphi-managed special entity. In particular, Delphi uses a Copy-On-Write
strategy, i.e. when you do P2^ := P1^;
, P1.str
and P2.str
both point to the same string object. Delphi keeps track via an internal reference count how many references to the string object exist.
As soon as you do a write operation like P2.str := P2.str + '_copy'
, Delphi recognises that the string is in use more than once and creates an own copy for P2.str. This all happens in the background and normally you don't notice this.
On the other hand, P3.strlist and P4.strlist are ordinary pointers and always point to the same object. There is no automagical copying here whatsoever.
Upvotes: 5
Reputation: 47809
Strings are copied on demand. That means when you change the copied string, it will create a new instance of the changed string. For simplicity you can assume that a string copy is a copy of the string data.
When you assign a class instance only a pointer to that instance is copied, not the instance itself. After the copy there is still only one class instance. You can see that from your code as there is only one TStringList.Create in your code.
Upvotes: 3
Reputation: 19106
You copy all the values from P3
to P4
.
But strlst
ist just a reference to an Object TStringList
and this reference is also copied and so P4.strlst
points to the same object as P3.strlst
Upvotes: 1
Reputation: 33283
It seems that delphi makes a shallow copy of objects. A shallow copy means that all native data types are copied but that objects are only copied by reference.
So after the copy assignment both objects hold a reference to the same strlist
object.
Upvotes: 2