あまり見当たらなかったので、備忘録がわりに公開しときます。
【メソッドポインタ経由でfunctionを呼び出すサンプル】
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; LabeledEdit1: TLabeledEdit; LabeledEdit2: TLabeledEdit; StaticText1: TStaticText; StaticText2: TStaticText; procedure OnCalcBtnClick(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} uses Unit2; type TMyCalcFunc = function(a,b : double) : double of object; procedure TForm1.OnCalcBtnClick(Sender: TObject); var MyCalc : TMyCalc; MyCalcFunc : TMyCalcFunc; Method: TMethod; begin MyCalc := TMyCalc.Create; try //Method.Data := MyCalc; if TButton(Sender).Caption = 'Add' then begin MyCalcFunc := MyCalc.Add; end else begin MyCalcFunc := MyCalc.Subtract; end; StaticText2.Caption := FloatToStr(MyCalcFunc(StrToFloat(LabeledEdit1.Text),StrToFloat(LabeledEdit2.Text))); finally MyCalc.Free; end; end; end.
【メソッドポインタ経由で呼び出されるクラスのサンプル】
unit Unit2; interface type TMyCalc = class function Add(a,b : double) : double; function Subtract(a,b : double) : double; end; implementation { TMyCalc } function TMyCalc.Add(a, b: double): double; begin Result := a + b; end; function TMyCalc.Subtract(a, b: double): double; begin Result := a - b; end; end.
メソッドポインタはヘルプにもあるように、
Type 型名 = "メソッドの定義" of object
のように宣言します。
ここで、"メソッドの定義"は、通常の手続き(関数)の名前を抜いたものになるので、
例えば、TObject型のSenderを引数に持ち、戻り値がない"メソッドの定義"は、
procedure(Sender : TObject)
同様に、Double型のaとbを引数に持ち、Double型の戻り値がある"メソッドの定義"は
function(a,b : Double) : Double
となります。
上記のサンプル1では、ボタンのキャプションに応じてif分で関数を切り替えています。
この例では、関数が2つだけなので、メソッドポインタ経由ではなく、直接目的の関数を
コールしたほうが良いのですが、
同じ型の引数を持つ関数が多数ある場合、メソッドポインタと、TObject.MethodAddressを
組み合わるとコード量を減らせる可能性があります。(上の例だとボタンのCaptionと関数名を
合わせおくことによりif文(あるいは、Case文)を無くすことが可能です。)
そのへんの話はまた後日・・・
0 件のコメント:
コメントを投稿