S
savetime
Unregistered / Unconfirmed
GUEST, unregistred user!
第二章最后一页。我注意到其中一句话:“类的vmt内容在第一个类对象创建时才会建立在内存中”。我当时的反应是:怎么可能?
李维举的例子好像是这样的:
var
AObject: TSomeObject;
AClass: Pointer;
begin
AClass := AObject.ClassType;
ShowVmtInfo(AClass);
AObject := TSomeObject.Create;
AClass := AObject.ClassType;
ShowVmtInfo(AClass);
end;
因为两次显示的vmt信息不同,所以李维下此结论。在此截取前几天我对类方法调用的汇编分析的代码:
var
Com: TComponent;
Str: String[255];
begin
Str := Com.ClassName;
lea edx, [ebp-$00000104]
mov eax, [ebp-$04]
eax = pointer to object
mov eax, [eax]
eax = pointer to VMT
call TObject.ClassName
可以看到,以对象调用类方法的时候,编译器生成的汇编代码仍然是以对象的地址查询到VMT指针的。所以李维的例子中,第一次调用 AClass := AObject.ClassType 并不能找到VMT的地址(因为对象还没有初始化),所以结论自然是错误的。我相信VMT的地址和内容在程序执行时就已经确定了。李维会得出这样的结论是不是因为受了C++的影响?(懂C++的人可以回忆一下local static object的内存地址和构造函数的调用时机,是不是与李维的想法有点类似?)
为了测试VMT是否在类的第一个对象创建前就存在,可以把李维的例子稍作修改,把对象方式的引用改为类引用:
var
AObject: TSomeObject;
AClass: Pointer;
begin
AClass := TSomeObject.ClassType
// 把原来的 AObject 改为 TSomeObject
ShowVmtInfo(AClass);
AObject := TSomeObject.Create;
AClass := AObject.ClassType;
ShowVmtInfo(AClass);
end;
我没有测试这个例子,有配书光盘的人可以试一下。
李维举的例子好像是这样的:
var
AObject: TSomeObject;
AClass: Pointer;
begin
AClass := AObject.ClassType;
ShowVmtInfo(AClass);
AObject := TSomeObject.Create;
AClass := AObject.ClassType;
ShowVmtInfo(AClass);
end;
因为两次显示的vmt信息不同,所以李维下此结论。在此截取前几天我对类方法调用的汇编分析的代码:
var
Com: TComponent;
Str: String[255];
begin
Str := Com.ClassName;
lea edx, [ebp-$00000104]
mov eax, [ebp-$04]
eax = pointer to object
mov eax, [eax]
eax = pointer to VMT
call TObject.ClassName
可以看到,以对象调用类方法的时候,编译器生成的汇编代码仍然是以对象的地址查询到VMT指针的。所以李维的例子中,第一次调用 AClass := AObject.ClassType 并不能找到VMT的地址(因为对象还没有初始化),所以结论自然是错误的。我相信VMT的地址和内容在程序执行时就已经确定了。李维会得出这样的结论是不是因为受了C++的影响?(懂C++的人可以回忆一下local static object的内存地址和构造函数的调用时机,是不是与李维的想法有点类似?)
为了测试VMT是否在类的第一个对象创建前就存在,可以把李维的例子稍作修改,把对象方式的引用改为类引用:
var
AObject: TSomeObject;
AClass: Pointer;
begin
AClass := TSomeObject.ClassType
// 把原来的 AObject 改为 TSomeObject
ShowVmtInfo(AClass);
AObject := TSomeObject.Create;
AClass := AObject.ClassType;
ShowVmtInfo(AClass);
end;
我没有测试这个例子,有配书光盘的人可以试一下。