またもや関数ポインタがうまく渡せなくなってしまいました…


おおさわ  URL  2005-02-24 21:12:27  No: 13422

二度目の質問をお許しください。
先ほどの関数渡しは成功したのですが、少し入れ子にしてプログラムを組んでみたところ、例外が発生してしまいました。

function Foo(Func: TFunction; x:Real): Real;
begin
  Result:= Func(x);
end;

function Bar(Func: TFunction; a: Real; t: Real): Real;
  function Quux(x: Real): Real;
  begin
    Result:= Func(x)*a;
  end;
begin
  Result:= Foo(@Quux, t);
end;

procedure Button2Click(Sender: TObject);
  function Half(x: Real): Real;
  begin
    Result:= x/2;
  end;
begin
  ShowMessage( FloatToStr( Bar( @Half, 3, 1 ) ) );
end;

Button2 を押すと、関数 Half に 3 をかけたものに、引数 x = 1 を代入した値を返す意図のプログラムを書きました。
しかし、「アドレス xxxxxxxx でアドレス xxxxxxxx に対する読み込み違反が発生しました。」と表示されてしまいます。
何か解決法はないものでしょうか?


りおりお  2005-02-24 21:47:31  No: 13423

関数内関数は外側の関数の引数が有効なのは、その関数から呼ばれたときだけです。
ですから、

  function Quux(x: Real): Real;
  begin
    Result:= Func(x)*a;
  end;

で、Foo から Quux が実行されるとき、Func と a は不定です。試しに

  function Quux(x: Real): Real;
  begin
    Result:= 1.23;
  end;

としてみると分かります。これは当然で、外側の関数と無関係に呼ばれてしまう場合に
正常に動くはずはないからです。


おおさわ  2005-02-24 22:08:37  No: 13424

ありがとうございます。確かにそう考えてみるとそうですね。
と、なると、同様の意図のプログラムは作ることはできないでしょうか?
何か別の形で実現することは可能ですか?


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加