object pascal对象的拷贝?(50分)

  • 主题发起人 主题发起人 6559026
  • 开始时间 开始时间
6

6559026

Unregistered / Unconfirmed
GUEST, unregistred user!
program strange;
{$APPTYPE CONSOLE}
uses SysUtils;
type
; T=class
; ; i:integer;
; ; end;
var
; t1,t2:T;
begin
; t1:=T.Create;
; t1.i:=1;
; t2:=T.Create;
// ;t2:=t1;
; t2.i:=2;
; write(t1.i);
; write(t2.i);
; readln;
; // Insert user code here
end.
此程序的输出为
1
2

如果把中间的注释语句t2:=t1;可执行,则输出为
2
2

显然这里是引用,求对象的拷贝方法,生成副本。
 
也许可以通过拷贝内存块的方法做到,但是如果
类中还有指向别处的指针或者引用就会有隐患

最安全的办法是自己做逐个成员的拷贝处理
 
program strange;
{$APPTYPE CONSOLE}
uses SysUtils;
type
; T=class
; ; i:integer;
; ; procedure Assign(Source: T);
; ; end;
implementation
; ; procedure T.Assign(Source: T);
; ; begin
; ; ; i := Source.i;
; ; end;
var
; t1,t2:T;
begin
; t1:=T.Create;
; t1.i:=1;
; t2:=T.Create;
// ;t2:=t1; ; ; ; ; ; ; ;<-还是不能这样用
; t2.Assign(t1);
; write(t1.i);
; write(t2.i);
; readln;
; // Insert user code here
end.


DELPHI自己都是这样写的。
 
我知道这个方法可以解决一部分,可是注意到我的问题:object pascal对象的拷贝?

如果两个对象是TObject,并不知道它的内部属性,怎么办?
T1,T2:TObject;
T2:=T1;


?????????
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=706176
 
坏兄,我会认真看看的。

我只想得到一个TObject类型变量的副本。
 
哦!说错了!!!
>>TObject没有任何成员函数,只有一堆方法,
应该是
TObject没有任何成员变量,只有一堆方法(成员函数),


不好意思,呵呵。。。
 
TObject没有任何成员变量,只有一堆方法(成员函数),
你打算复制什么呢?

看看TPersistent类定义吧,如果你理解了Virtual方法的作用,
procedure TPersistent.Assign(Source: TPersistent);
你会明白DELPHI是怎么实现对象拷贝的,
实际上比你考虑的更多。
 
多谢,另一问题

为什么这种程序居然可以运行?
program Project2;
{$APPTYPE CONSOLE}
uses SysUtils;
type
; T=class
; ; i:integer;
; ; end;
var
; t1:T;
begin
; t1:=T.Create;
; t1.i:=1;
; t1.Free;
; write(t1.i);
; readln;
; // Insert user code here
end.
 
DELPHI的对象变量实际上是对象指针变量,而对象本身存在于堆上,
动态创建的对象、字符串、数组。。。。。都是在堆上分配内存,
所以尽管你释放了t1,但你没有t1 := nil,因此它仍然指向那块内存,
如果尚未将这块内存分配做它用,你还是可以访问它的。

试试下面这段,你认为它会输出几呢?

program Project1;
{$APPTYPE CONSOLE}
uses SysUtils;

type
TMyClass = class
i: Integer;
end;

var
O1, O2: TMyClass;

begin
O1 := TMyClass.Create;
O1.i := 1;
O1.Free;
O2 := TMyClass.Create;
O2.i := 2;
O2.Free;
Writeln(O1.i);
Readln;
end.
 
也就是说并没有真正的free掉

看看我理解的对不对
O1 := TMyClass.Create;//分配O1的空间X
O1.i := 1; ; ; ; ; ; ;
O1.Free; ; ; ; ; ; ; ;//free了,但是O1仍然是X的引用
O2 := TMyClass.Create;//在X上分配O2
O2.i := 2;
O2.Free; ; ; ; ; ; ; ;//这下。O1/O2都是X的引用
Writeln(O1.i); ; ; ; ;//所以当然,输出2
 
You are right! Nice boy !!!
 
这个TObject类型变量的副本还真难得到阿。
 
首先,哥们儿,你认为复制TObject有意义吗?它没有一个成员变量啊!!!!!!!!!



其次,看看下面的代码,你就理解Delphi是怎么实现对象拷贝的了,Delphi确实就是这么做的!

program Project1;
{$APPTYPE CONSOLE}
uses SysUtils;

type
TG1 = class
procedure Assign(Src: TG1); virtual; abstract;
end;

TF1 = class(TG1)
Age: Integer;
procedure Assign(Src: TG1); override;
end;

TF2 = class(TG1)
Color: Integer;
procedure Assign(Src: TG1); override;
end;

TSon = class(TF1)
Length: Integer;
procedure Assign(Src: TG1); override;
end;

{ TF1 }

procedure TF1.Assign(Src: TG1);
begin
inherited;
if Src is TF1 then
Age := (Src as TF1).Age;
end;

{ TF2 }

procedure TF2.Assign(Src: TG1);
begin
inherited;
if Src is TF2 then
Color := (Src as TF2).Color;
end;

{ TSon }

procedure TSon.Assign(Src: TG1);
begin
inherited;
if Src is TSon then
Length := (Src as TSon).Length;
end;

var
Father: TF1;
Uncle: TF2;
You: TSon;
begin
Father := TF1.Create; Father.Age := 88;
Uncle := TF2.Create; ;Uncle.Color := 100;
You := TSon.Create;

You.Assign(Father); //你知道这句干了什么吗?
You.Assign(Uncle); //你知道这句又干了什么吗?

Father.Assign(Uncle); //这句呢?
Father.Assign(You); //???

Uncle.Assign(Father); //??
Uncle.Assign(You); //??

Father.Free; Uncle.Free; You.Free;
end.


只不过你非要用赋值的方式来“Copy”对象,才能满足你的“心理”拟或“生理”需求吗?
C++能这么做,是因为它支持运算符重载,即使你自己没有重载“=”运算符,在你进行对象间赋值时,
C++也帮你重载了,并调用了缺省的“拷贝构造函数”。
而“运算符重载”已被公认为“弊大于利”,好象C#和JAVA都不支持运算符重载。



最后再说说昨天的问题,其实那个先释放对象、再使用对象的程序并不总是返回2,
如果在O1.Free之后,你的进程用完了时间片,被挂起并交换到磁盘上,O2将不一定
分配在O1原来的位置上,而且再次使用O1还可能"Access violation....."。
 
各位讲的很好,[:D]
 
你说的一切我都明白,
可是,TObject在delphi的定义中是没有任何变量,他是一切对象的‘老爸’,假若以
下程序执行之后:
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils;
type
T=class
;i:integer;
;end;
var
; t1:T;
; o1:TObject;
begin
; t1:=T.create;
; t1.i:=123;
; o1:=t1;
end.
o1这个TObject类型的表链不就有成员变量了吗?可以用(o1 as T).i来访问。

假设有一个a:array [1..10] of TObject,我怎么往里面增加元素?
难道为了安全我必须
var
t1:T;
i:integer;
begin
for i:=1 to 10 do
;begin
; t1:=T.create;
; t1.i:=123;
; a[1]:=t1;
; t1:=nil; ;//free不行,照样可以用;destroy delphi也不赞成直接用,而对象的复制又是引用 ; ; ;
end;

本以为delphi中有我不知道的拷贝对象的函数……我只是想以一种不需知道对象的结构就可以拷贝
对象的方法。

就像a,b:array of integer;
a:=copy(b)

我能读懂你的程序,可你说的"Access violation....."。(os嘛)

声明:谢谢坏兄(其实一点也不坏)。呵呵
 
我能读懂你的程序,~~~和~~~你说的"Access violation....."。(os嘛)

我的意思是当o1,o2被赋了值,拷贝就有意义了。
 
后退
顶部