Delphi:如何将所有 class 字段重置为零值?
Delphi: How can I reset all class fields to zero value?
我有一个 class 有很多数字字段,字段的数量会随着项目的发展而增加,所以如果有一种方法可以重置所有字段,无论将来添加多少.
TParams = class
public
defined: boolean;
FirstValue: byte; // reset from here
A0: single;
A1: single;
H1: TPoint;
// ...............
A100: single;
LastValue: byte; // to here
procedure Reset;
end;
想到的唯一想法是插入 2 个字段:应该重置的块之前和之后,并使用 FillMemory:
procedure TParams.Reset;
begin
FillMemory(@FirstValue, Integer(@LastValue)-Integer(@FirstValue),0);
end;
有没有更好的方法? (我正在使用 Delphi 7)
在某些受限制的情况下,例如您使用 TParams
的情况,调用 InitInstance 应该可以解决问题:
procedure TParams.Reset;
begin
InitInstance(Self);
end;
David Heffernan 已经说过了:你正在做的是一个丑陋的 hack,而且不是很干净。他还给出了提示:把你的数字字段变成一条记录:
type
TParams = class
public
Defined: Boolean;
Numbers: record
A0: Single;
A1: Single;
H1: TPoint;
A100: Single;
end;
procedure Reset;
end;
现在就很简单了,你可以Reset
通过下面的操作:
procedure TParams.Reset;
begin
FillChar(Numbers, SizeOf(Numbers), 0);
end;
一个简单的测试:
procedure Test;
var
P: TParams;
begin
P := TParams.Create;
try
Writeln(Format('%f %f (%d, %d) %f', [P.Numbers.A0, P.Numbers.A1, P.Numbers.H1.X, P.Numbers.H1.Y, P.Numbers.A100]));
P.Numbers.A0 := 1.0;
P.Numbers.A1 := 2.0;
P.Numbers.H1 := Point(11, 22);
P.Numbers.A100 := 77.0;
Writeln(Format('%f %f (%d, %d) %f', [P.Numbers.A0, P.Numbers.A1, P.Numbers.H1.X, P.Numbers.H1.Y, P.Numbers.A100]));
P.Reset;
Writeln(Format('%f %f (%d, %d) %f', [P.Numbers.A0, P.Numbers.A1, P.Numbers.H1.X, P.Numbers.H1.Y, P.Numbers.A100]));
finally
P.Free;
end;
end;
这会产生以下输出:
0.00 0.00 (0, 0) 0.00
1.00 2.00 (11, 22) 77.00
0.00 0.00 (0, 0) 0.00
或者,您可以执行以下操作:
TNumbers = record
A0: Single;
A1: Single;
H1: TPoint;
A100: Single;
end;
TParams = class
public
Defined: Boolean;
Numbers: TNumbers;
procedure Reset;
end;
对于那些带有泛型的版本(我知道您使用的是 Delphi 7,它没有泛型,但无论如何,对于其他版本),这将简化 Reset
一点:
procedure TParams.Reset;
begin
Numbers := Default(TNumbers);
end;
Default
的优点是它将正确地完成和初始化记录,以防万一它在其中管理类型(字符串、接口等)。
我有一个 class 有很多数字字段,字段的数量会随着项目的发展而增加,所以如果有一种方法可以重置所有字段,无论将来添加多少.
TParams = class
public
defined: boolean;
FirstValue: byte; // reset from here
A0: single;
A1: single;
H1: TPoint;
// ...............
A100: single;
LastValue: byte; // to here
procedure Reset;
end;
想到的唯一想法是插入 2 个字段:应该重置的块之前和之后,并使用 FillMemory:
procedure TParams.Reset;
begin
FillMemory(@FirstValue, Integer(@LastValue)-Integer(@FirstValue),0);
end;
有没有更好的方法? (我正在使用 Delphi 7)
在某些受限制的情况下,例如您使用 TParams
的情况,调用 InitInstance 应该可以解决问题:
procedure TParams.Reset;
begin
InitInstance(Self);
end;
David Heffernan 已经说过了:你正在做的是一个丑陋的 hack,而且不是很干净。他还给出了提示:把你的数字字段变成一条记录:
type
TParams = class
public
Defined: Boolean;
Numbers: record
A0: Single;
A1: Single;
H1: TPoint;
A100: Single;
end;
procedure Reset;
end;
现在就很简单了,你可以Reset
通过下面的操作:
procedure TParams.Reset;
begin
FillChar(Numbers, SizeOf(Numbers), 0);
end;
一个简单的测试:
procedure Test;
var
P: TParams;
begin
P := TParams.Create;
try
Writeln(Format('%f %f (%d, %d) %f', [P.Numbers.A0, P.Numbers.A1, P.Numbers.H1.X, P.Numbers.H1.Y, P.Numbers.A100]));
P.Numbers.A0 := 1.0;
P.Numbers.A1 := 2.0;
P.Numbers.H1 := Point(11, 22);
P.Numbers.A100 := 77.0;
Writeln(Format('%f %f (%d, %d) %f', [P.Numbers.A0, P.Numbers.A1, P.Numbers.H1.X, P.Numbers.H1.Y, P.Numbers.A100]));
P.Reset;
Writeln(Format('%f %f (%d, %d) %f', [P.Numbers.A0, P.Numbers.A1, P.Numbers.H1.X, P.Numbers.H1.Y, P.Numbers.A100]));
finally
P.Free;
end;
end;
这会产生以下输出:
0.00 0.00 (0, 0) 0.00
1.00 2.00 (11, 22) 77.00
0.00 0.00 (0, 0) 0.00
或者,您可以执行以下操作:
TNumbers = record
A0: Single;
A1: Single;
H1: TPoint;
A100: Single;
end;
TParams = class
public
Defined: Boolean;
Numbers: TNumbers;
procedure Reset;
end;
对于那些带有泛型的版本(我知道您使用的是 Delphi 7,它没有泛型,但无论如何,对于其他版本),这将简化 Reset
一点:
procedure TParams.Reset;
begin
Numbers := Default(TNumbers);
end;
Default
的优点是它将正确地完成和初始化记录,以防万一它在其中管理类型(字符串、接口等)。