Delphi 5开发人员第二章 的一段话,如何理解?(10分)

  • 主题发起人 主题发起人 delhpi
  • 开始时间 开始时间
D

delhpi

Unregistered / Unconfirmed
GUEST, unregistred user!
Object Pascal提供了两个运算符a s和i s,用它们通过RT T I 能对对象进行比较和强制类型转换。
关键字as 是类型转换的一种新的形式。它能把一个基层的对象强制类型转换成它的派生类,如果转换不合法就产生一个异常。假定有一个过程,想让它能够传递任何类型的对象,它应该这样定义:
procedure Foo(AnObject:TObject);

在这个过程如果要对A n O b j e c t进行操作,要把它转换为一个派生对象。假定把A n O b j e c t看成是一个T E d i t派生类型,并想要改变它所包含的文本( T E d i t是一个Delphi VCL编辑控件),用下列代码:
(Foo As TEdit).text:='holle World';
能用比较运算符来判断两个对象是否是相兼容的类型,用is 运算符把一个未知的对象和一个已知类型或实例进行比较,确定这个未知对象的属性和行为。例如,在对A n O b j e c t进行强制类型转换前,
确定A n O b j e c t和T E d i t是否指针兼容:
if (Foo Is TEdit) then
TEdit(Foo).text:='Hello,World.';

注意在这个例子中不能用a s进行强制类型转换,这是因为它要大量使用RT T I ,另外还因为,在第一行已经判断F o o就是T E d i t,可以通过在第2行进行指针转换来优化。

==========
注意在这个例子中不能用a s进行强制类型转换,这是因为它要大量使用RT T I
==========
这是因为它要大量使用RT T I ,是什么意思?是不是这样 代码运行时,效率比较低?



==========
假定把A n O b j e c t看成是一个T E d i t派生类型,并想要改变它所包含的文本( T E d i t是一个Delphi VCL编辑控件),用下列代码:
(Foo As TEdit).text:='holle World';
===========
这段话是否有误?我理解是
(AnObject As TEdit).text:='holle World';



富翁名称: delhpi
专 家 分: 6
可用积分: 15
给10分
 
(Foo As TEdit).text:='holle World';
显然是笔误,Foo是过程名啊。
 
==========
注意在这个例子中不能用a s进行强制类型转换,这是因为它要大量使用RT T I
==========
这是因为它要大量使用RT T I ,是什么意思?是不是这样 代码运行时,效率比较低?
 
RTTI就是运行时才确定的类型信息。
当然没有在编译的时候就确定类型信息来得快,因为此时编译器可以针对这个类型来优化处理。
RTTI: Run Time Type Information.
以上理解不是是否正确,请高手指教。
 
正是这个疑问。
 
RTTI是运行期类型信息。这里的说法应该有错,是“不宜用”,不是“不能用”。原因是用Foo As TEdit时,系统会先判断Foo是否是TEdit或TEdit的子类,所以会浪费一点时间。用TEdit(Foo)是不做任何判断的指针类型转换,速度比as快,但如果Foo不是TEdit就无法预测这个操作的结果(可能内存读写错,也可能正常赋值,也可能内存泄漏)。上面的写法中,因为转换之前已经判断了if Foo is TEdit,所以用TEdit(Foo)是安全的。
 
有时间,要找原来的英文看看。
 
......能看英文还是看英文吧。上面的译法问题不少

原文是:Object Pascal provides two operators, is and as, that allow comparisons and typecasts of objects via RTTI.
他译:Object Pascal提供了两个运算符a s和i s,用它们通过RT T I 能对对象进行比较和强制类型转换。
问题:typecasts只是“类型转换”,不是“强制类型转换”。TEdit(Foo)这样写才是“强制类型转换”。用As是“安全类型转换”

原文是:Notice that you didn’t use the as operator to perform the typecast in this example.
他译:注意在这个例子中不能用a s进行强制类型转换
问题:就算是直译,也只是“这里不用。。。是因为。。。”,而不是“这里不能用。。。。”。而且全文都用一般现在时(从前面可以notice看出),这里用了过去时,因此只是在说一个特例,或者是虚拟语气。如果说不能,应该用"you can't..."或者"you will not..."

原文是:That’s because a certain amount of overhead is involved in using RTTI.
他译:这是因为它要大量使用RT T I
实际是:“这是因为它在使用RTTI时损耗了一定的效率”,用as做类型转换并不会“大量使用RTTI”。if ... is ... + tedit(...)用的CPU时间应该大于或等于 Foo as TEdit。在这里不用,主要是因为已经用了if...is...
=======================================================
除了第一个procedure Foo(AnObject : TObject)外,其他的Foo应该是原文笔误,应改成AnObject
 
谢谢。

is as 都用到RTTI
is 是类型比较
as 是安全类型转换 速度慢。


TEdit(xxx) 不用RTTI
是强制类型转换,速度快,实际使用时,如果xxx的类型不能确定一定是TEdit,推荐先is 判断一下,这样就安全了。

菜鸟的理解对吗?
 
as只是转换之前用RTTI判断一下,对速度影响不大, 而且明显的类型错误在编译期会报错. 作者的意思是, 如果之前已经用 if foo is TEdit 判断过了,就不需要用as了. is的判断其实也是用RTTI信息, 而且编译期不会报错. 因此总的来说, 用foo as TEdit直接转, 比 if foo is TEdit then TEdit(foo)要快.

但两者的行为是不一样的. foo as TEdit如果错误明显, 在编译期就会报错. 如果在编译期无法判断, 就会抛运行期异常. if foo is TEdit then TEdit(foo)不会抛异常, 不合条件就什么都不干. 所以要根据实际需求来选择.
 
更正了一下上面的说法, as对明显的错误会在编译期报错, 但运行期仍然会照做检查, 因此速度不变. 但如果你逻辑上认为B必定是A的子类,而实际上不是,编译期错误比运行时直接跳过要好得多. 因此, 能用as的地方还是建议用as.
 
应该是这样的:因为大量使用RTTI,所以不推荐使用。从逻辑上看,已经判断了对象的类型,因此,直接类型转换是合理的选择。
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部