в Delphi 5, всегда ли параметр TList передается по ссылке? - PullRequest
1 голос
/ 09 июля 2020

Я переношу код с Delphi 5 на современную платформу. В настоящее время у меня есть скомпилированный код (который работает в моей среде) и исходный код (который не может быть скомпилирован в моей среде). Это означает, что я не могу экспериментировать с кодом, изменяя его, вставляя точки останова или сбрасывая значения. Глядя на один конкретный фрагмент кода, я вижу, что одна Процедура (Процедура А) вызывает другую (Процедуру В) и передает параметры, которые должны быть переданы по ссылке, поскольку в противном случае Процедура В не имела бы никакого эффекта. Насколько я понимаю, к параметрам в списке параметров процедуры необходимо добавить префикс var, чтобы они передавались по ссылке, но здесь этого не делается. Однако один из параметров относится к типу TList, который, как мне известно, по сути является массивом указателей. Мой вопрос: параметры типа TList (а также другие, имеющие отношение к указателям) неявно передаются по ссылке?

Вот код:

Procedure ProcedureB(PartyHeaderInformationPtr : PartyHeaderInformationPointer;
                                                PartyHeaderTable : TTable;
                                                _PrisonCode : String;
                                                _FineType : TFineTypes;
                                                PartyHeaderInformationList : TList);

begin
  with PartyHeaderInformationPtr^, PartyHeaderTable do
    begin
      AssessmentYear := FieldByName('TaxRollYr').Text;
      PartyType := FieldByName('PartyType').Text;
      PartyNumber := FieldByName('PartyNo').AsInteger;
      PrisonCode := _PrisonCode;
      FineType := _FineType;

    end;  {with PartyHeaderInformationPtr^ ...}

  PartyHeaderInformationList.Add(PartyHeaderInformationPtr);

end;  {AddPartyHeaderPointerInformation}

{=================================================================}
Procedure ProcedureA(PartyHeaderTable : TTable;
                                              PartyDetailTable : TTable;
                                              PartyHeaderInformationList : TList);

var
  Done, FirstTimeThrough : Boolean;
  PrisonPartyFound, JunglePartyFound : Boolean;
  PrisonPartyYear, PrisonCode, PartyType : String;
  PartyHeaderInformationPtr : PartyHeaderInformationPointer;

begin
  PartyHeaderTable.Last;
  PrisonPartyYear := '';
  PrisonPartyFound := False;
  JunglePartyFound := False;
  Done := False;
  FirstTimeThrough := True;

  repeat
    If FirstTimeThrough
      then FirstTimeThrough := False
      else PartyHeaderTable.Prior;

    If PartyHeaderTable.BOF
      then Done := True;

    If not Done
      then
        begin
          PartyType := PartyHeaderTable.FieldByName('PartyType').Text;

          If ((not JunglePartyFound) and
              ((PartyType = 'MU') or
               (PartyType = 'TO')))
            then
              begin
                JunglePartyFound := True;

                New(PartyHeaderInformationPtr);

                AddPartyHeaderPointerInformation(PartyHeaderInformationPtr,
                                                      PartyHeaderTable,
                                                      '', ltPlace,
                                                      PartyHeaderInformationList);

              end;  {If ((not JunglePartyFound) and ...}

        end;  {If not Done}

  until Done;

end;  {FillPartyHeaderInformationList}

1 Ответ

8 голосов
/ 09 июля 2020

Да .

В Delphi, классы являются ссылочными типами.

Каждая переменная типа TBitmap, TList , TButton, TStringList, TForm и c. не что иное, как указатель на объект, поэтому объект всегда передается «по ссылке». Только этот адрес, это целое число собственного размера, передается вызываемой подпрограмме. обращайтесь к нему. Но сам указатель передается по значению, поэтому, если вызываемая процедура изменяет указатель параметра на другой объект, вызывающий не увидит этого; изменяется только копия адреса вызываемой подпрограммы. В var указатель сам передается по ссылке, поэтому вызываемая подпрограмма также может это изменить: она может изменить исходный объект и может заставить переменную вызывающей стороны указывать на другой объект, если захочет.

С другой стороны, типы значений, такие как целые числа, логические значения, наборы, статические c массивы и записи, передаются по значению, поэтому - без какого-либо оформления параметров, например var - вызываемая процедура получает копию , и любые изменения вносятся только в эту копию. Вызывающий не увидит изменения своей переменной. Однако, если вы используете параметр var, переменная будет передана по ссылке.

Итак, в вашем случае это не имеет ничего общего с тем, что TList является "списком" или является чем-то, что " содержит указатели ". Это примерно TList класс.

...