一个令人头痛的问题,请求得到您的帮助。如何将一个类实例复制到另一个类对象上?(200分)

  • 主题发起人 徐凤华
  • 开始时间

徐凤华

Unregistered / Unconfirmed
GUEST, unregistred user!
简单的说,程序中有两个类实例
var
ClassA, ClassB: TMyClass;

使用什么方法才能将ClassA的复制到ClassB上?
 
你是指所有类成员都相等的复制吗?类似于赋值操作
 
直接赋值就可以了呀。
 
CLASSA,CLASSB 他们的属性,方法实现是怎么样的?
再详细点。
 
什么方法实现???
 
如果用ClassB:=ClassA只是指针改变,ClassB原来的内存没有释放会造成内存泄漏
用下面语句吧:
ClassB.Assign(ClassA)
 
这个需要在TMyClass的定义中重载AssignTo方法,在这个方法中把自身的所有属性都赋给Dest参数的相关属性,然后在程序中调用Assign方法来赋值,正如zhongs兄说的那样:ClassB.Assign(ClassA);
Assign方法会直接调用AssignTo方法;

而且TMyClass必须要从TPersistent继承上来,

请看TPicture的源码:

TPicture = class(TInterfacedPersistent, IStreamPersist)
private
...............
protected
procedure AssignTo(Dest: TPersistent)
override;
...........
end;

procedure TPicture.AssignTo(Dest: TPersistent);
begin
if Graphic is Dest.ClassType then
Dest.Assign(Graphic)
else
inherited AssignTo(Dest);
end;
 
如果就是这个简单的类的话,简单:
type
MyClass=class
public
a:Integer;
end;

var
x, y: MyClass;
Size: Integer;
begin
x := NewClass.Create;
x.i := 15;
Size := x.InstanceSize;
y := NewClass(x.NewInstance);
Move(Pointer(x)^, Pointer(y)^, Size);
ShowMessage('Y.i: ' + IntToStr(y.i));
y.i := 17;
ShowMessage('X.i: ' + IntToStr(x.i))
// 仍然是 15,因此互不影响
y.Free;
x.Free;
end;

当然了,要是你这个类中间还包括诸如 对象啦、长字符串啦、指针啦什么的,就不能
这样做了。那些东西是需要额外分配空间的。要是那样反正我想不出简单的办法:(

 
Assign 不是 TObject 的方法.
看来只有复制内存空间.
 
将self 转化为指针,PPointer(integer(self))

vmtSelfPtr = -76;
vmtIntfTable = -72;
vmtAutoTable = -68;
vmtInitTable = -64;
vmtTypeInfo = -60;
vmtFieldTable = -56;
vmtMethodTable = -52;
vmtDynamicTable = -48;
vmtClassName = -44;
vmtInstanceSize = -40;
vmtParent = -36;
vmtSafeCallException = -32;
vmtAfterConstruction = -28;
vmtBeforeDestruction = -24;
vmtDispatch = -20;
vmtDefaultHandler = -16;
vmtNewInstance = -12;
vmtFreeInstance = -8;
vmtDestroy = -4;

vmtQueryInterface = 0;
vmtAddRef = 4;
vmtRelease = 8;
vmtCreateObject = 12;
 
leizengzheng:这样是不够的,和我的方法一样,只能对简单的域起作用。
如果类中包含指针、对象等另外分配的空间,不算在 InstanceSize 内,
这样就不行了:(

 
是啊,要有动态分配内的或创建的对象是不能仅仅用assign就可以解决问题的。重载
该方法就如c++里的拷贝函数一样。
 
最安全最保验的方法就是自己写一个Assign方法,具体可以参照TPersistent的Assign方法和Assignto方法来写.
 
多谢诸位大哥帮我解决问题。
 

Similar threads

S
回复
0
查看
986
SUNSTONE的Delphi笔记
S
S
回复
0
查看
804
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
顶部