【发布时间】:2011-04-20 05:28:40
【问题描述】:
在 Delphi 中,如果我有一个简单的类 myClass,并且我将它的一个实例传递给带有 myFunction( myClass ) 的函数,该函数由 function myFunction( myObject : myClass ) : Boolean 定义...
是否会制作 myObject 的副本?
当我在myFunction中调用myObject的方法时,原来的对象也会受到影响和修改吗?
【问题讨论】:
在 Delphi 中,如果我有一个简单的类 myClass,并且我将它的一个实例传递给带有 myFunction( myClass ) 的函数,该函数由 function myFunction( myObject : myClass ) : Boolean 定义...
是否会制作 myObject 的副本?
当我在myFunction中调用myObject的方法时,原来的对象也会受到影响和修改吗?
【问题讨论】:
对象通过引用传递。不会制作副本;将只有一个类的实例,只有一个对象。原来的对象就是一切。
【讨论】:
对象通过引用传递。
【讨论】:
除了“对象通过引用传递”之外,还有更多内容。对象是引用类型,因此默认情况下它们总是通过引用传递。任何对象变量都是对象引用。
但是,如果您“通过引用”传递对象变量(传递给 var 参数),那么如果您在传递给它的例程中将对象替换为不同的对象,您将一旦例程返回,最终会得到一个不同的对象。这样做时要小心;如果更改对某个对象的唯一引用,可能会导致内存泄漏。
【讨论】:
TObject 的变量时存在如此普遍的误称,MyForm.Width...MyForm.Width 是其引用由 MyForm 变量保存的 Form 的实际宽度。您更改了MyForm 变量,MyForm.Width 是另一个表单的宽度。所以,“你最终会得到一个不同的对象”在一定程度上描述了程序员在实践中的现实。
在 Delphi 中,对象是特殊的指针,它指向堆内存上的数据结构。当您将对象传递给函数时,您实际上是在传递指针,而不是整个对象数据的副本。在这种情况下,当您通过该引用修改字段或属性时,它将影响原始对象数据。这是一个演示此行为的简单示例:
program ObjParamTest;
type
TMyClass = class
private
FMyField : Integer;
public
property MyField : Integer read FMyField write FMyField;
end;
function ModifyObject(AnObj: TMyClass);
begin
AnObj.MyField := AnObj.MyField + 1;
end;
var
MyObj : TMyClass;
begin
MyObj := TMyClass.Create;
try
AnObj.MyField := 2;
Writeln(AnObj.MyField); // ==> Prints 2
ModifyObject(MyObj);
Writeln(AnObj.MyField); // ==> Prints 3
finally
MyObj.Free;
end;
end.
还要注意,参数修饰符(例如 Var、Const、Out)只改变对象引用传递给函数的方式,对原始数据结构没有影响。
也许这篇文章为您更清楚地了解了在 Delphi 中将参数传递给函数的不同方式:
【讨论】:
AnObj在主体中应改为MyObj