Pointers 在Delphi5中,TList参数是否总是通过引用传递?
我正在将一些代码从Delphi5迁移到现代平台。目前,我有在我的环境中工作的已编译代码和无法在我的环境中编译的源代码。这意味着我不能通过更改代码、插入断点或转储值来真正体验代码。在查看一段特定的代码时,我看到一个过程ProcedureA正在调用另一个ProcedureB并传入必须通过引用的参数,否则ProcedureB将无效。我的理解是,必须将var前缀添加到过程的参数列表中的参数,以便通过引用传递它们,但这里没有这样做。不过,其中一个参数是TList类型,我知道它本质上是一个指针数组。我的问题是:TList类型的参数以及其他参数是否必须通过引用隐式传递指针 代码如下:Pointers 在Delphi5中,TList参数是否总是通过引用传递?,pointers,delphi,pascal,Pointers,Delphi,Pascal,我正在将一些代码从Delphi5迁移到现代平台。目前,我有在我的环境中工作的已编译代码和无法在我的环境中编译的源代码。这意味着我不能通过更改代码、插入断点或转储值来真正体验代码。在查看一段特定的代码时,我看到一个过程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}
对
在Delphi中,是引用类型
TBitmap、TList、TButton、TStringList、TForm等类型的每个变量都是指向对象的指针,因此对象总是通过引用传递。只有这个地址,这个本机大小的整数,才被赋予被调用的例程
因此,即使没有var,被调用的例程也可以更改对象,因为它与调用者一样,具有指向它的地址。但是指针本身是通过值传递的,因此如果被调用的例程更改参数指针以指向不同的对象,调用方将看不到这一点;只更改被调用例程的地址副本。使用var时,指针本身是通过引用传递的,因此被调用的例程也可以改变这一点:它可以改变原始对象,如果需要,它可以使调用方的变量指向不同的对象
另一方面,值类型(如整数、布尔值、集合、静态数组和记录)是按值传递的,因此,在没有任何参数修饰(如var)的情况下,被调用的例程将获得一个副本,所做的任何更改都只对该副本进行。调用者将看不到其变量被修改。但是,如果使用var参数,变量将通过引用传递
因此,在您的例子中,它与TList是一个列表或是包含指针的东西无关。这是关于TList是一个类。是的
在Delphi中,是引用类型
TBitmap、TList、TButton、TStringList、TForm等类型的每个变量都是指向对象的指针,因此对象总是通过引用传递。只有这个地址,这个本机大小的整数,才被赋予被调用的例程
因此,即使没有var,被调用的例程也可以更改对象,因为它与调用者一样,具有指向它的地址。但是指针本身是通过值传递的,因此如果被调用的例程更改参数指针以指向不同的对象,调用方将看不到这一点;只更改被调用例程的地址副本。使用var时,指针本身是通过引用传递的,因此被调用的例程也可以改变这一点:它可以改变原始对象,如果需要,它可以使调用方的变量指向不同的对象
另一方面,值类型(如整数、布尔值、集合、静态数组和记录)是按值传递的,因此,在没有任何参数修饰(如var)的情况下,被调用的例程将获得一个副本,所做的任何更改都只对该副本进行。调用者将看不到其变量被修改。但是,如果使用var参数,变量将通过引用传递
因此,在您的例子中,它与TList是一个列表或是包含指针的东西无关。它是关于TList是一个类。更准确地说,你应该写const,它通过引用传递记录和字符串。还有关于out,它是指仅通过引用值得出的结果。@ArnaudBouchez:我考虑过这样做,也考虑过写动态数组和字符串,甚至可能是接口,但犹豫地决定不写,为了不偏离Q的主题太多。常量不会总是通过引用传递。Const是给编译器的一个信号,它不仅指示被调用方无法修改该值,还提示编译器选择传递参数的最有效方式。对于整数,它仍将按值传递,可能在CPU寄存器中。但是,如果类型的大小不适合寄存器,则将通过引用传递。规则比这复杂一点,但这是本质。艾伦是对的。const参数可以用[Ref]修饰,以指示编译器通过引用传递它。更准确地说,你应该写一下const,它通过引用传递记录和字符串。还有关于out,它只用于参考值的结果。@ArnaudBouchez:我考虑过这样做,而且w
写关于动态数组和字符串的文章,甚至可能是接口,但犹豫地决定不写,为了不偏离Q的主题太多。常量不会总是通过引用传递。Const是给编译器的一个信号,它不仅指示被调用方无法修改该值,还提示编译器选择传递参数的最有效方式。对于整数,它仍将按值传递,可能在CPU寄存器中。但是,如果类型的大小不适合寄存器,则将通过引用传递。规则比这复杂一点,但这是本质。艾伦是对的。const参数可以用[Ref]修饰,以指示编译器通过引用传递它。