「スマートポインタ、使ってる? – 全力わはー」のエントリーを読んで、ソースコードの
type
Auto<T: class> = reference to function: T;
TAuto<T: class> = class(TInterfacedObject, Auto<T>)
…
のところがわからなかったので調べてみました。
無名メソッドとは
無名メソッドは、名前のない手続き・関数です。
「reference to procedure」型や「reference to function」型の変数に代入できます。
以下のコードは、「reference to procedure」型の変数に無名メソッドを代入して使用する例です。
type
TFuncOfPrint = reference to procedure(S: string);
var
Func: TFuncOfPrint;
begin
Func := procedure(S: string)
begin
WriteLn(S);
end;
Func('Hello world!');
end.
詳しくはdocwikiの「無名メソッド – RAD Studio」をご覧ください。
無名メソッドはインターフェース
無名メソッド型はインターフェースとして実装されています。
次のDelphiのコードをC++Builderでコンパイルすると
type
TFunc<T> = reference to function: T;
TProc<T> = reference to procedure(Value: T);
このようなコードが生成されます。
template<typename T> __interface TFunc__1 : public System::IInterface
{
public:
virtual T __fastcall Invoke(void) = 0 ;
};
template<typename T> __interface TProc__1 : public System::IInterface
{
public:
virtual void __fastcall Invoke(T Value) = 0 ;
};
つまり
type
TFunc<T> = reference to function: T;
は、
type
TFunc<T> = interface
function Invoke(): T;
end;
と同じ考えて良さそうです。
無名メソッドを継承する
インターフェースであることから、継承も可能です。
type
TFunc<T> = reference to function: T;
TFunc2<T> = interface(TFunc<T>)
end;
TFunc3<T> = class(TInterfacedObject, TFunc<T>)
public
function Invoke(): T;
end;
無名メソッド型の変数に代入もできます。
type
TFunc<T> = reference to function: T;
TFunc3<T> = class(TInterfacedObject, TFunc<T>)
private
FValue: T;
public
constructor Create(Value: T);
function Invoke(): T;
end;
constructor TFunc3<T>.Create(Value: T);
begin
FValue := Value;
end;
function TFunc3<T>.Invoke: T;
begin
Result := FValue;
end;
var
Func: TFunc<Integer>;
begin
Func := TFunc3<Integer>.Create(100);
WriteLn(Func);
end.
さいごに
スマートポインタ便利そうですね。