下面的项目无法以"访问冲突"错误运行.我使用Delphi XE2 Update 3.
program Project1;
{$APPTYPE CONSOLE}
type
TTestClass = class
public
class procedure Test;
end;
var
TestClass: TTestClass;
class procedure TTestClass.Test;
begin
end;
begin
TestClass.Test;
end.
Run Code Online (Sandbox Code Playgroud)
如果我标记class procedure Test
为"静态",则没有问题.这是'设计'吗?
PS:这是我的错,对我很羞耻.
是的,你目睹的是正确的.
与实例方法一样,非静态类方法具有隐藏Self
参数.对于类方法,它引用类引用.这就像编译器将您的方法转换为:
type
TTestClassClass = class of TTestClass;
procedure TTestClass_Test(Self: TTestClassClass);
Run Code Online (Sandbox Code Playgroud)
当您在非类接收器(即对象引用)上调用类方法时,编译器会插入一个调用,ClassType
以使用对象的运行时类型填充该参数,如下所示:
TTestClass_Test(TestClass.ClassType);
Run Code Online (Sandbox Code Playgroud)
该ClassType
方法获取对象的VMT的地址,但您的变量不引用任何VMT.您的变量是空指针或未初始化,因此如果您很幸运,尝试取消引用它以读取VMT地址会导致访问冲突.(如果你运气不好,它会取消引用地址,而地址恰好位于程序地址空间的其他地方,并且结果被解释为VMT指针,即使它不是.)
仅对类引用或有效对象引用调用类方法.
TTestClass.Test;
Run Code Online (Sandbox Code Playgroud)
当您在类引用"文字"上调用它时,编译器已经知道第一个参数的值并转换调用,如下所示:
TTestClass_Test(TTestClass);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
318 次 |
最近记录: |