一个非常非常奇怪的问题??? ( 积分: 0 )

  • 主题发起人 主题发起人 lovellybaby
  • 开始时间 开始时间
L

lovellybaby

Unregistered / Unconfirmed
GUEST, unregistred user!
//定义一个记录
type test=record
s,k:string;
end;
//赋值
var ttest:test;
ttest.s:='demo';//没问题
ttest.k:='demo';//没问题
-----------------------------------------------
//把该记录定义为类的成员
type tdemo=class
ftest:test;
constructor create;
...
...
property testrecord:test read ftest write ftest;
...
end;
//在程序中使用demo属性
var demo:tdemo;
demo:=tdemo.create;
{
demo.testrecord.s:='demo';//出错,显示不能赋植。
demo.testrecord.k:='demo';//同上。
}
with demo.testrecord do
begin
s:='demo';//没问题。
k:='demo';//每问题。
end;

请问用了With do语句就没有了问题,With除了开域难道Delphi编译器还插入了其他汇编语句????
 
//定义一个记录
type test=record
s,k:string;
end;
//赋值
var ttest:test;
ttest.s:='demo';//没问题
ttest.k:='demo';//没问题
-----------------------------------------------
//把该记录定义为类的成员
type tdemo=class
ftest:test;
constructor create;
...
...
property testrecord:test read ftest write ftest;
...
end;
//在程序中使用demo属性
var demo:tdemo;
demo:=tdemo.create;
{
demo.testrecord.s:='demo';//出错,显示不能赋植。
demo.testrecord.k:='demo';//同上。
}
with demo.testrecord do
begin
s:='demo';//没问题。
k:='demo';//每问题。
end;

请问用了With do语句就没有了问题,With除了开域难道Delphi编译器还插入了其他汇编语句????
 
我自认为对Delphi Language很了解,看来我错了!!
 
你可以直接对FTest操作:
FTest.s :='Demo';
FTest.k :='Demo';
但对属性testrecord就不能这样
 
但是如果再纪录中定义如k:TstringList;
demo.testrecord.k.add('demo');//没有错误,注意是通过属性访问。
以上做何解释?
 
此记录成员没有分配内存,应该在类crates时初始化ftest
 
record只能整体赋值,而不能进行部分赋值,这是它作为属性时比较特殊的地方。而with do的作用其实是把属性实际操作的变量ftest的地址放在EAX寄存器中(这里是读对象的属性),然后根据EAX和ftest的字段偏移来访问各个字段域的内容的,这就相当于先把ftest放到了一个临时record变量中,然后对这个临时record变量的字段进行读写,这时候就不再涉及到类的对象的属性写操作了。
不过仍然可以象这样定义属性来部分访问读写record的。
property s: string read ftest.s write ftest.s;
至于demo.testrecord.k.add('demo');//没有错误,注意是通过属性访问。
这个和什么的对属性进行写操作,已经没有关系了,demo.testrecord.k这里是读操作,而add是方法调用,和前面的情况有着本质的区别,比如demo.testrecord.k := nil;就不行,当然demo.testrecord.k.Delimiter := ',';这是可以的,因为k本身是个类对象。
 
同意lichengbin,似乎是这么个理。
 
后退
顶部