在实际应用中,静态类方法和常规函数指针似乎是兼容的,但编译器并不知道这一点。例如:
type
TFunc = function(i: Integer): string;
TMyClass = class
public
class function StaticMethod(i: Integer): string; static;
end;
class function TMyClass.StaticMethod(i: Integer): string;
begin
Result := '>' + IntToStr(i) + '<';
end;
function GlobalFunc(i: Integer): string;
begin
Result := '{' + IntToStr(i) + '}';
end;
procedure CallIt(func: TFunc);
begin
Writeln(func(42));
end;
begin
CallIt(TMyClass.StaticMethod); // 1a: doesn't compile
CallIt(GlobalFunc); // 1b: compiles
CallIt(@TMyClass.StaticMethod); // 2a: compiles iff $TYPEDADDRESS OFF
CallIt(@GlobalFunc); // 2b: compiles iff $TYPEDADDRESS OFF
CallIt(Addr(TMyClass.StaticMethod)); // 3a: compiles
CallIt(Addr(GlobalFunc)); // 3b: compiles
Readln;
end.
如评论中所述,3a和3b都编译通过(其中编译包括在此简单示例中在运行时工作)。当且仅当$TYPEDADDRESS
为OFF
时,2a和2b才会同时编译通过。但是1a/1b有所不同:1b总是编译通过,而1a从不编译通过。这种区别是否是有意设计的?使用3a是否安全或我忽略了任何潜在问题?
CallIt(@TMyClass.StaticMethod);
运行良好。 - kludg$TYPEDADDRESS ON
。 - Uli GerhardtAddr()
对{$T+}是免疫的,而@
则不是。这在文档中有说明。 - Sertac Akyuz