在 Delphi 5 中,是否总是通过引用传递 TList 参数?

Gus*_*ler 1 delphi pascal pointers

我正在将一些代码从 Delphi 5 迁移到现代平台。目前我有编译后的代码(在我的环境中工作)和源代码(在我的环境中无法编译)。这意味着我无法通过更改或插入断点或转储值来真正试验代码。在查看一段特定的代码时,我看到一个过程 (ProcedureA) 正在调用另一个过程 (ProcedureB) 并传入必须通过引用的参数,否则 ProcedureB 将不起作用。我的理解是必须在过程的参数列表中的参数中添加 var 前缀,以便它们通过引用传递,但这里没有这样做。但是,其中一个参数是 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}

Run Code Online (Sandbox Code Playgroud)

And*_*and 8

是的

在 Delphi 中,是引用类型。

型中的每个变量TBitmapTListTButtonTStringListTForm等等是只是一个指向对象,所以对象被“按引用”始终通过。只有这个地址,这个本地大小的整数,才被提供给被调用的例程。

因此,即使没有var,被调用的例程也可以更改对象,因为它像调用者一样拥有指向它的地址。但是指针本身是按值传递的,所以如果被调用的例程改变参数指针指向不同的对象,调用者将看不到;只有被调用例程的地址副本被更改。使用var,指针本身是通过引用传递的,所以被调用的例程也可以改变它:它可以改变原始对象,如果它愿意,它可以使调用者的变量指向不同的对象。

另一方面,像整数、布尔值、集合、静态数组和记录这样的值类型是按值传递的,因此——没有任何参数修饰,例如var——被调用的例程获得一个副本,并且所做的任何更改只会对那个副本。调用者不会看到它的变量被修改。var但是,如果使用参数,则变量将通过引用传递。

因此,就您而言,它与TList成为“列表”或“包含指针”的事物无关。这是关于TList成为一个班级。