СИТУАЦИЯ. Я создал модуль с некоторыми классами для решения вопросов алгебры (сравнения и системы), я показываю вам код:
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
. Во второй строке, кстати, есть некоторые проблемы, которых я не могу понять.
Конструктор имеет var result: integer
, поэтому я могу получить побочный эффект от переданной переменной, а затем я могу назначить resInner := result;
. В конце (в очереди) я даю resInner
значение sysResult и ожидаю, что 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;
Где giveMeSolution
- это просто простая процедура, использующая переменную a
, содержащую результат системы. Если это невозможно, что я могу сделать? По сути, результат в конце Execute - это просто целое число, которое нужно передать в основной поток.
Я читал о ReturnValue
, но не уверен как это использовать.