3

状況。代数の問題 (合同とシステム) を解決するために、いくつかのクラスを含むユニットを作成しました。コードを示しています。

type
 TCongrError = class(Exception)
 end;

type
 TCongruence = class(TComponent)
  //code stuff
  constructor Create(a, b, n: integer); virtual;
 end;

type
 TCongrSystem = array of TCongruence;

type
 TCongruenceSystem = class(TThread)
  private
   resInner: integer;
   FData: TCongrSystem;
   function modinv(u, v: integer): integer; //not relevant
  protected
   procedure Execute; override;
  public
   constructor Create(data: TCongrSystem; var result: integer; hasClass: boolean);
 end;

TThreadこのクラスには、コンストラクターに渡されるパラメーターの長さが原因で完了するまでに時間がかかる可能性のある Execute メソッドがあるため、使用することにしました。実装は次のとおりです。

constructor TCongruenceSystem.Create(data: TCongrSystem; var result: integer; hasClass: boolean);
begin

 inherited Create(True);
 FreeOnTerminate := true;

 FData := data;
 setClass := hasClass;
 resInner := result;

end;

procedure TCongruenceSystem.Execute;
var sysResult, i, n, t: integer;
begin

 sysResult := 0;
 n := 1;

 //computation

 Queue( procedure
        begin
         ShowMessage('r = ' + sysResult.ToString);
         resInner := sysResult;
        end );

end;

問題

を見るとQueue、ShowMessage を (テストとして) 使用していて、正しい値の が表示されていることがわかりますsysResult。ところで、2行目には理解できない問題があります。

コンストラクターにはvar result: integer、渡された変数から副作用を与えることができるので、代入できresInner := result;ます。最後に (Queue で) resInnersysResult の値を指定していresultますvar。なぜこれが起こらないのですか?

次のようにコンストラクターを変更する別のテストを行いました。

constructor TCongruenceSystem.Create(data: TCongrSystem; result: TMemo; hasClass: boolean);
//now of course I have resInner: TMemo

キューを次のように変更します。

Queue( procedure
        begin
         ShowMessage('r = ' + sysResult.ToString);
         resInner.Lines.Add(sysResult.ToString);
        end ); //this code now works properly in both cases! (showmessage and memo)

コンストラクターでは、参照である TMemo を渡していますが、元のものvar result: integerも参照として渡されていませんか? ではなぜうまくいかないのでしょうか?

私はこのようなことをしたいので、これをしたい:

 //I put var a: integer; inside the public part of the TForm
 test := TCongruenceSystem.Create(..., a, true);
 test.OnTerminate := giveMeSolution;
 test.Start;
 test := nil;

Whereは、システムの結果を含むgiveMeSolution変数を使用する単純な手順です。aこれが不可能な場合、どうすればよいですか? 基本的に、Execute の最後の結果は、メイン スレッドに渡す必要のある単なる整数です。

読んだことがありますReturnValueが、使い方がわかりません。

4

2 に答える 2