type Tmyclass = class(TObject)
somearray: array of TSometype
FBool: Boolean;
Fint: Integer;
Fstr: string;
constructor Create;
destructor Destroy; override;
end;
implementation
constructor Tmyclass.Create;
begin
inherited;
SetLength(somearray,0); //is this needed?
end;
destructor TmyClass.Destroy;
begin
SetLength(somearray,0); //this IS needed!
inherited;
end;
还有哪些类型在创建时被初始化?例如我在课堂上宣布的内容。 FBool被保证是假的吗? 是FInt保证是0吗? 是Fstr保证是''?
当地人怎么样?只有字符串?
我使用的是Delphi XE。
答案 0 :(得分:13)
属于对象的所有内存在对象构造(堆分配)时初始化为0,因此通常不需要初始化属于某个类的任何内容,默认值(零内存)是:
等等。
对于局部变量和与堆栈相关的任何东西,它将包含垃圾,因此您需要在使用变量之前提供有意义的值。
类似的东西:
procedure Something;
var
x: Integer;
begin
ShowMessage(IntToStr(X));
end;
将显示随机值。
答案 1 :(得分:13)
动态数组是托管类型,因此始终初始化为nil
,相当于SetLength(..., 0)
。你永远不需要这样做。
唯一可以捕获的是当您从过程返回动态数组作为函数返回值时。事实上,函数返回值实际上只是一个隐式的var参数。
请考虑以下代码:
function Foo: string;
begin
Result := Result + 'X';
end;
var
i: Integer;
begin
for i := 1 to 5 do
Writeln(Foo);
Writeln(Foo);
Writeln(Foo);
end;
<强>输出强>
X
XX
XXX
XXXX
XXXXX
X
X
这里发生的是编译器作为优化选择不重新初始化循环内的隐式局部变量。
这可能会不时地引起你的注意,所以我建议设置为nil返回值,这些值是动态数组,字符串,接口等。对于类成员你不需要这样做,并且让构造函数为零更为惯用 - 自动初始化它们。
答案 2 :(得分:7)
两个 SetLength调用都是多余的,因为动态数组已初始化并完成。
类实例中的所有字段都初始化为各自的零值,即0,nil,False,'等等。
仅当局部变量属于生命周期管理类型(如字符串,动态数组或接口)时,才初始化(并最终确定)局部变量。
答案 3 :(得分:4)
正如其他回答者所说,你不需要初始化类成员字段。
您还询问了局部变量。是的,您需要初始化它们。所有这些,除了其中一个托管类型的变量:
来自Barry Kelly在Sertac在评论中指出的答案的清单:Which variables are initialized when in Delphi?
答案 4 :(得分:0)
如果您事先知道阵列的大小,将它作为一个整体进行分配可能是一个好习惯,它将在以后避免过多的重新分配,更好地使用内存。当你不再使用它时清除数组会释放它的内存(但Delphi知道如何在它们超出范围时清除它们)。