2016-07-30 77 views
3

我有一个有许多数字字段的类,字段的数量会随着项目开发而增长,所以如果有一种方法可以重置所有字段,无论将来会添加多少字段,都会很好。Delphi:如何将所有类字段重置为零值?

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; 

有没有更好的办法? (IM采用Delphi 7)

+2

将所有字段放入记录并将记录置零。不要像这样使用丑陋的黑客。 –

+1

清零不会最终确定任何“受管理”成员。如果只有数字字段,则零化无误。 –

回答

6

大卫·赫弗南已经说的那样:你在做什么是一个丑陋黑客,并不是很干净。他也给了暗示:将您的数字字段到一个记录:

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的优点是,它会正常完成并初始化记录,以防万一它在它管理的类型(字符串,接口等)。

+0

谢谢!我知道fiedls可以被打包成记录,只是虽然有一些方法不这样做..现在我知道没有其他方式:) –

+1

我同意不把它们放在记录中会更方便,因为你可以立即以“P.A0”等方式访问它们,而不是“P.Numbers.A0”。但除了单独初始化所有的字段(如果只有少数几个没有大的话,尽管如果你添加了一个字段,你可能会忘记设置一个字段),这个记录是唯一干净的解决方案。一旦你可以升级到现代版本的Delphi,使用更清洁的'Default',而不是'ZeroMemory'或'FillChar'或类似的。 –

+0

FWIW,您可以使用两个空记录(“FirstValue:record end;”),而不是像FirstValue和LastValue那样使用标记*字节*。 ;-)但说实话,把尼姑放在自己的记录里就是一个干净的解决方案。 –

2

在某些受限制的情况下喜欢你的情况与TParams是,到InitInstance中调用应该做的伎俩:

procedure TParams.Reset; 
begin 
    InitInstance(Self); 
end; 
+2

不会调用'InitInstance'也设置他的'defined'字段回到'False'? OP不是试图重置所有的类字段,而只是其中的一部分。 – SilverWarior

+2

@SilverWarior,是的。如果需要,我不知道。我只是指问题的“重置所有领域的方法”部分。顺便说一句,如果有托管类型的字段,它也会失败。 –