2016-07-30 5 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つのフィールドを挿入することです:resetedれるべきブロックの前と後、およびFillMemoryを使用します。

procedure TParams.Reset; 
begin 
    FillMemory(@FirstValue, Integer(@LastValue)-Integer(@FirstValue),0); 
end; 

がより良い方法ですか? TParamsとあなたのケースのようないくつかの制限されたシナリオで

+2

レコードにすべてのフィールドを置き、レコードをゼロにします。このような醜いハックを使わないでください。 –

+1

ゼロ化では、「管理された」メンバーはファイナライズされません。数値フィールドしかない場合、ゼロ化は問題ありません。 –

答えて

6

デビッドHeffernanのは、すでにそれを言った:何をやっていることは醜いですハック、それほど清潔ではない。それは、あなたが行うことによってReset非常にシンプルな、次のことができている今

type 
    TParams = class 
    public 
    Defined: Boolean; 
    Numbers: record 
     A0: Single; 
     A1: Single; 
     H1: TPoint; 
     A100: Single; 
    end; 
    procedure Reset; 
    end; 

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; 
レコードにあなたの数値フィールドをONにする:彼はまた、ヒントを与えました

これにより、次の出力が生成されます。

0.00 0.00 (0, 0) 0.00 
1.00 2.00 (11, 22) 77.00 
0.00 0.00 (0, 0) 0.00 
ジェネリック医薬品とバージョン(私はあなたが他の人のために、とにかく何もジェネリックを持っていないデルファイ7を使用して、されますが、知っている)、その意志を持つ人のために

TNumbers = record 
    A0: Single; 
    A1: Single; 
    H1: TPoint; 
    A100: Single; 
    end; 

    TParams = class 
    public 
    Defined: Boolean; 
    Numbers: TNumbers; 
    procedure Reset; 
    end; 


また、次の操作を行うことができますResetを少し簡素化:

procedure TParams.Reset; 
begin 
    Numbers := Default(TNumbers); 
end; 

Defaultは、それはそれでの型(文字列、インタフェースなど)を管理しているだけの場合には、それが適切にレコードを確定し、初期化するという利点を有します。

+0

ありがとう!私はfiedlsがレコードに詰め込まれる可能性があることを知っていましたが、それをしない方法がいくつかあります。今私は他の方法がないことを知っています:) –

+1

レコードに入れない方が便利でしょう。 'P.Numbers.A0'の代わりに即座に' P.A0'などとしてアクセスしてください。しかし、すべてのフィールドを別々に初期化することとは別に(フィールドが追加された場合は1つを設定することを忘れても、少数しかない場合は大したことはありません)、レコードは唯一のクリーンなソリューションです。また、Delphiの現代版にアップグレードすると、ZeroMemoryやFillCharなどの代わりに、よりクリーンな 'Default'を使用することができます。 –

+0

FWIWでは、FirstValueやLastValueのようにmarker * bytes *を使用する代わりに、2つの空のレコード( "FirstValue:record end;")を使用できました。 ;-)しかし、正直言って、ナンバーを自分の記録に入れることはきれいな解決策です。 –

2

(イムは、Delphi 7を使用して)のInitInstanceの呼び出しはトリックを行う必要があり、次のとおりです。

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

'InitInstance'も' defined'フィールドを 'False'に設定していませんか? OPはすべてのクラスフィールドをリセットするのではなく、その一部だけをリセットしようとしています。 – SilverWarior

+2

@ SilverWarior、そうです。これが望まれるなら、私は知識がありません。私は質問の「すべてのフィールドをリセットする方法を持つ」という部分だけを指しています。また、管理されたタイプのフィールドがある場合は失敗します。 –

関連する問題