静的なクラスメソッドと通常のルーチンポインタは実用的な観点から互換性がありますが、コンパイラはこれを知らないようです。例:コメント、3aに述べたように静的クラスメソッドと通常のルーチンポインタはどのように互換性がありますか?
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.
及び3bは両方コンパイル(がをコンパイルこの単純な例で実行時に作品を含みます)。 2aおよび2bは、$TYPEDADDRESS
がOFF
の場合にのみコンパイルされます。しかし、1a/1bは異なります。1bは常にコンパイルしますが、1aはコンパイルしません。これは設計上の区別ですか? 3aを使用していますか、落とし穴を見落としましたか?
'CallIt(@ TMyClass.StaticMethod);'はうまく動作します。 – kludg
言及を忘れた:私は '$ TYPEDADDRESS ON'を使用する。 –
@Ulrich - Sergは既に 'Addr()'が{$ T +}に対して免疫されておらず、 '@'はそうでないという答えを出しました。これは[ドキュメント](http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/System_Addr.html)です。 –