您的位置:首页 > 其它

⊙ is 和 as 运算符的原理

2013-02-25 14:32 387 查看
Come Form: http://blog.csdn.net/jubobo/article/details/6749698

⊙ is 和 as 运算符的原理

===============================================================================

我们知道可以在运行期使用 is 关键字判断一个对象是否属于某个类,可以使用 as 关键字把某个对象安全地转换为某个类。在编译器的层次上,is 和 as 的操作是由 System.pas 中两个函数完成的。

{ System.pas }

function _IsClass(Child: TObject; Parent: TClass): Boolean;

begin

Result := (Child <> nil) and Child.InheritsFrom(Parent);

end;

_IsClass 很简单,它使用 TObject 的 InheritsForm 函数判断该对象是否是从某个类或它的父类中继承下来的。每个类的 VMT 中都有一项 vmtParent 指针,指向该类的父类的 VMT。TObject.InheritsFrom 实际上是通过[递归]判断父类 VMT 指针是否等于自己的 VMT 指针来判断是否是从该类继承的。

{ System.pas }

class function TObject.InheritsFrom(AClass: TClass): Boolean;

var

ClassPtr: TClass;

begin

ClassPtr := Self;

while (ClassPtr <> nil) and (ClassPtr <> AClass) do

ClassPtr := PPointer(Integer(ClassPtr) + vmtParent)^;

Result := ClassPtr = AClass;

end;

as 操作符实际上是由 System.pas 中的 _AsClass 函数完成的。它简单地调用 is 操作符判断对象是否属于某个类,如果不是就触发异常。虽然 _AsClass 返回值为 TObject 类型,但编译器会自动把返回的对象改变为 Parent 类,否则返回的对象没有办法使用 TObject 之外的方法和数据。

{ System.pas }

function _AsClass(Child: TObject; Parent: TClass): TObject;

begin

Result := Child;

if not (Child is Parent) then

Error(reInvalidCast); // loses return address

end;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: