*** 对象赋值 ***(200分)

  • 主题发起人 主题发起人 savenight
  • 开始时间 开始时间
S

savenight

Unregistered / Unconfirmed
GUEST, unregistred user!
TMyClass=class(TObject)
private
Fdata1:integer;
Fdata2:double;
Fdata3:boolean;
procedure fa;
function fb;
end;

var
class1,class2:TMyClass;
i:integer;
begin
class1:=TMyClass.create;
class2:=TMyClass.create;
for i:=0 to Max do
begin
//-----------------
对class1的数据进行操作
//------------------
class2:=class1
//1。
//-----------------
对class2的数据进行操作
//------------------
class1:=class2
//2。
end;

请问:
:: 在1,2处,class1的值是否完全付给了class2,还是只赋了指针?
:: 如要把class1的每一个变量值,和过程赋给class2,怎样做?
::每次循环,我希望class2会自动清空变量(就象刚刚初始化是一样,boolean 是false,integer,double是0)
是不是只有释放,再重建?


 
class1:=class2;是指针赋值
class1.assign(class2);是复制内存
class2可以free然后再重新创建的了
 
看看Delphi的help


Call Assign to copy the properties or other attributes of one object from another. The standard form of a call to Assign is

Destination.Assign(Source);
 
下面这个方法不知道对你最后一个问题是否有用
initializes a newly allocated object instance to all zeros and initializes the instance抯 virtual method table pointer.

class procedure InitInstance(Instance: Pointer): TObject;

Description

There should be no reason to call InitInstance directly. InitInstance is called automatically by NewInstance when an object is created. When overriding NewInstance be sure to call InitInstance as the last statement.

InitInstance is not virtual, so you cannot override it: Instead, initialize any data for an object in the constructor.
 
1. 在delphi中类的实例变量本身就是一个指针, 所以类之间的赋值只传递了一个指针.
2. 直接赋值就可以了.
3. 声明一个方法负责处理类似的事情.
 
〉〉class1.assign(class2);是复制内存
tobject没有assign。
是不是class2:=class1后,对class2的操作也会影响class1?
最后一个问题,请给一个最有效的,明确的答案。

谢谢上面的二位。
 
class2:=class1后,对class2的操作也会影响class1?

是的. class2的操作其实就是操作class1,他们指向的是同一地址,就和变量参数一样。
要注意的是你在操作class2的过程中如果释放了class1,程序就会出现异常。这种情况下你最好
用class1.assign(class2);
 
对,会影响class1
我说的复制内存就是复制一个对象,assign是从
TPersistent.assign才开始有的
 
同意楼上的
 
上面的赋值是赋指针无疑。
如果在c++下,应该自己编一个用于复制的构造函数。
我想在delphi下应该也差不多。
 
3. 声明一个方法负责处理类似的事情, 然后在循环中调用
 
重新创建class2,然后class2.xxx:=class1.xxx;
 
Brave:
tpersistent 中的assign也只是个空架子,还是要我自己建。这和从tobject直接继承
再建一个处理过程有什么不一样?
前两个问题和我的原来想法一样。我想问的是如果tobject继承的话该怎样处理?

对于第三个问题,我好像没说明白。
我的意思是,class2只需要class1的某个属性值,其他的属性清空。
因为在循环中,我只操作class1的某个属性值,而其他的属性存放的是参考变量,如果是用assign的话,
那么进入下一个循环后,其他的属性值里还是原来的值,那我的程序会出错。


再次谢谢各位
 
1. 仅赋了指针
2.
>>tobject继承的话该怎样处理?
Just use:

type
TMyClass=class(TObject)
Fdata1:integer;
Fdata2:double;
Fdata3:boolean;
fa:Procedure
//
fb:function:Boolean
//
end;
procedure TForm1.Button1Click(Sender: TObject);
var
class1,class2:TMyClass;
i:integer;
PC1,PC2:PChar;
begin
class1:=TMyClass.create;
class1.Fdata1:=123;
class1.Fdata2:=456.789;
class1.Fdata3:=true;
class2:=TMyClass.create;
PC1:=Pointer(Integer(class1)+4)
//数据开始地址
PC2:=Pointer(Integer(class2)+4)
//数据开始地址
System.Move(PC1^,PC2^,TMyClass.InstanceSize-4)
//整体复制数据 HERE!
end;

3.
>>其他的属性清空
自己写一个Init过程就可以了,然后直接赋值,OK?
 
creation-zy:
〉〉 PC1:=Pointer(Integer(class1)+4)
//数据开始地址
〉〉 PC2:=Pointer(Integer(class2)+4)
//数据开始地址
〉〉 System.Move(PC1^,PC2^,TMyClass.InstanceSize-4)
//整体复制数据 HERE!
可否解释一下为什么 +4 -4?

3.
因为其他属性比较多,处理比较复杂,而且我必须保证进入下一轮循环时,其他属性为空,
即初始化状态。我现在采用的办法是在循环中先free,再create,这样如果循环10000此的话,
我也就free,create10000,我不知这样对效率是否有影响?(总觉得这个办法很蠢)

 
可以建一个构造函数
constructor create(Fdata1:integer
Fdata2:double
Fdata3:boolean;)
 
creation-zy:
请回答我的问题,分都是你的了。
 
看看指针操作,OK?
 
搞明白了,原来TPersistent 里根本就没有实现Assign,只是提供了一个虚拟方法,具体实现还得靠自己。
(就像我提的这个问题还是得靠自己解决一样)[:D]
代码:
  TPersistent = class(TObject)
  public
    procedure Assign(Source: TPersistent)
virtual;

下面是我做的一个简单的例子,希望给初学者一点帮助。
TBase=class(TPersistent)
public
Fdata1:integer;
Fdata2:double;
procedure Assign(Source: TPersistent);override;
end;

TMy=class(TBase)
public
Fbase:TBase;
Fdata:integer;
procedure Assign(Source: TPersistent);override;
end;
//...
implementation
//....
{ TBase }
procedure TBase.Assign(Source: TPersistent);
begin
Fdata1:=(source as TBase).Fdata1
Fdata2:=(source as TBase).Fdata2
// inherited;
end;
{ TMy }
procedure TMy.Assign(Source: TPersistent);
begin
inherited;
Fdata:= (source as TMy).Fdata;
Fbase:= (source as TMy).Fbase;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
base1,base2:TBase;
my1,my2:TMy;
begin
base1:=TBase.Create;
base1.Fdata1 :=23;
base1.Fdata2 :=3.3;
base2:=TBase.Create;
base2.Assign(base1);
my1:=TMy.Create;
my1.Fbase :=base1;
my1.Fdata :=100;
my2:=TMy.Create;
my2.Assign(my1);
end;
////////////////////////////////////////////////
最后还是希望creation-zy兄解释一下您的做法,只要您发言我立马结束这个帖子,谢谢!
 
指针的老问题。
 
后退
顶部