1 一个对象指针指向的一个对象的数据区,该数据区前面4个字节是一个指针,指向的是大名鼎鼎的VMT,其实是Self的地址,代码如下:
procedure TForm1.btn3Click(Sender: TObject);
var
Chld: TChild;
P1, p2, p3, p4: Pointer;
begin
Chld := TChild.Create;
try
//对象指针
P1 := Chld;
mmo1.Lines.Add(Format('Chld Obj at:$%s', [IntToHex(Integer(P1), 8)]));
p2 := Pointer(P1^);
//P2 P2指向的正式VMT的零地址
mmo1.Lines.Add(Format('Chld Pointer at:$%s', [IntToHex(Integer(P2), 8)]));
p3 := Pointer(Integer(p2) + vmtSelfPtr);
mmo1.Lines.Add(Format('Self Pointer at:$%s', [IntToHex(Integer(P3), 8)]));
p4 := Pointer(p3^);
mmo1.Lines.Add(Format('Self Pointer at:$%s', [IntToHex(Integer(P4), 8)]));
{
Chld Obj at:$00952544
Chld Pointer at:$0044FAF4
Self Pointer at:$0044FAA8
Self Pointer at:$0044FAF4
}
finally
FreeAndNil(Chld);
end;
end;
看到第二个指针的地址与第四个地址相同既可以说明问题
2 有些方法在编译时已经确定了地址就可以不用创建对象而直接操作方法
1) 静态方法,且不涉及类的私有数据
2 )类方法
注意几点:
1> 其实1)本身可以写成类方法
2> 类方法可以直接用类名来访问,也可以用未创建的对象指针来访问,当然也可以用实际有指向对象的指针变量来访问
3> 类方法在实现时会检测是否真的没有访问私有数据,由此可见,对于那些未涉及私有数据的方法,声明为类方法是很方便的
4> 其他方法或者数据都需要通过Self指针来定位,故一定要用创建了类对象的指针来访问