类定义之后,在运行时,TXXClass到底是什么(100分)

  • 主题发起人 主题发起人 poy
  • 开始时间 开始时间
P

poy

Unregistered / Unconfirmed
GUEST, unregistred user!
定义一个类:
TMyClass =class
class procedure test;
end;
class procedure TMyClass.test;
begin
//
end;

//应用 -------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var
obj :TMyClass ;
begin
obj:= TMyClass.Create ;
TMyclass.test ;
end;
我想搞明白。些时的TMyClass到底是什么,于是打开CPU 看到的是
mov dl,$01
mov eax ,[$0047dac] //这行把TMyClass的地址推 入eax中
call TObject.Create
我想知道,在内存中,[$0047dac]这块地址到底是些什么内容?
原以为dephi中的class function与C++中的static方法应该 是一样没有self指针的,可是当看CPU时却意外发现编译器依旧 mov eax ,[$0047dac] ,这又有何用?
请高人指点。
 
這裡的self是類的地址,不是實例的地址,
TMyClass =class
class procedure test;
end;
class procedure TMyClass.test;
begin
with self.create do
begin
...
end;
end;
 
这是一个类方法,不需要创建实例就可以调用
 
楼上两位所述的我知道 ,可是没有解决我的疑问。
 
指向虚方法表的指针。基本上可以认为顺着指针过去就是这个类的虚方法表,当然,还有别的东西,要了解细节可以参考周爱民的那本书。
 
主要目的是要调用虚拟方法表(Vitual Method Table,简称 VMT)中的虚函数NewInstance完成对象实例的创建、部分初始化。另外,设置函数 _AfterConstruction 是调用 VMT 中的虚函数AfterConstruction。
跟入 call tobject.create 看看可以发现调用TObject的Create构造函数,而TObject的Create构造函数调用了系统的ClassCreate过程。系统的ClassCreate过程又通过调用TObject类的虚方法NewInstance。调用TObject的NewInstance方法的目的是要建立对象的实例空间。TObjec类的NewInstance方法将根据编译器在类信息数据中初始化的对象实例尺寸(InstanceSize),调用GetMem过程为该对象分配内存。然后调用TObject类InitInstance方法将分配的空间初始化。InitInstance方法首先将对象空间的头4个字节初始化为指向对象类的VMT的指针,然后将其余的空间清零。建立对象实例最后,还调用了一个虚方法AfterConstruction。最后,将对象实例数据的地址指针保存到Obj变量中,这样,Obj对象就诞生了。
 
我认为理解这个问题,可能要要注意一个问题:
C#中的静态方法是不可以作为虚拟方法virutal和override的。
但是Delphi中却可以,也就是说,在基类中的静态方法,可以在派生类中覆盖,那么这些方法就有可能放在了VMT中,
在这个时候Self就变得有意义了!同一个方法名称,不同的TxxxClass可能是不一样的!

而楼主提到的[$0047dac] 其实就是指向TxxxClass的类的类型指针!这个指针就是VMT的指针。其实就是系统提供了一个就算没有对象实例也能访问类的VMT的途径!
 
后退
顶部