在 Delphi 5,TList 参数总是通过引用传递吗?
in Delphi 5, is a TList parameter always passed by reference?
我正在将一些代码从 Delphi 5 迁移到现代平台。目前我有编译代码(在我的环境中工作)和源代码(不能在我的环境中编译)。这意味着我无法通过更改代码或插入断点或转储值来真正试验代码。在查看一段特定的代码时,我看到一个过程 (ProcedureA) 正在调用另一个过程 (ProcedureB) 并传递必须通过引用传递的参数,否则 ProcedureB 将无效。据我了解,必须将 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}
是.
在Delphi中,classes是引用类型。
TBitmap
、TList
、TButton
、TStringList
、TForm
等类型的每个变量都不过是指向对象的指针,所以对象总是“通过引用”传递。只有这个地址,这个本机大小的整数,被提供给被调用的例程。
因此,即使没有 var
,被调用的例程也可以更改对象,因为它和调用者一样,拥有它的地址。但是指针本身是按值传递的,因此如果被调用例程更改参数指针以指向不同的对象,调用者将看不到;只有被调用例程的地址副本被更改。使用 var
,指针本身通过引用传递,因此被调用的例程也可以更改它:它可以更改原始对象,并且可以使调用者的变量指向另一个对象,如果需要的话。
另一方面,像整数、布尔值、集合、静态数组和记录这样的值类型是按值传递的,所以——没有任何参数修饰,比如var
——被调用的例程得到一个副本,并且所做的任何更改仅对该副本进行。调用者不会看到其变量被修改。但是,如果您使用 var
参数,变量将通过引用传递。
因此,在您的情况下,它与 TList
是“列表”或“包含指针”的东西无关。这是关于 TList
成为 class.
我正在将一些代码从 Delphi 5 迁移到现代平台。目前我有编译代码(在我的环境中工作)和源代码(不能在我的环境中编译)。这意味着我无法通过更改代码或插入断点或转储值来真正试验代码。在查看一段特定的代码时,我看到一个过程 (ProcedureA) 正在调用另一个过程 (ProcedureB) 并传递必须通过引用传递的参数,否则 ProcedureB 将无效。据我了解,必须将 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}
是.
在Delphi中,classes是引用类型。
TBitmap
、TList
、TButton
、TStringList
、TForm
等类型的每个变量都不过是指向对象的指针,所以对象总是“通过引用”传递。只有这个地址,这个本机大小的整数,被提供给被调用的例程。
因此,即使没有 var
,被调用的例程也可以更改对象,因为它和调用者一样,拥有它的地址。但是指针本身是按值传递的,因此如果被调用例程更改参数指针以指向不同的对象,调用者将看不到;只有被调用例程的地址副本被更改。使用 var
,指针本身通过引用传递,因此被调用的例程也可以更改它:它可以更改原始对象,并且可以使调用者的变量指向另一个对象,如果需要的话。
另一方面,像整数、布尔值、集合、静态数组和记录这样的值类型是按值传递的,所以——没有任何参数修饰,比如var
——被调用的例程得到一个副本,并且所做的任何更改仅对该副本进行。调用者不会看到其变量被修改。但是,如果您使用 var
参数,变量将通过引用传递。
因此,在您的情况下,它与 TList
是“列表”或“包含指针”的东西无关。这是关于 TList
成为 class.