2016-07-30 6 views
3

많은 숫자 필드가있는 클래스가 있습니다. 필드 수가 프로젝트 개발과 함께 커지므로 미래에 얼마나 많은 요소가 추가 되더라도 모든 필드를 다시 설정하는 것이 좋습니다.Delphi : 모든 클래스 필드를 어떻게 0으로 재설정 할 수 있습니까?

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

더 나은 방법이 있나요 : FillMemory을 전 reseted해야한다 블록 후 및 사용

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 개 필드를 삽입하는 것입니다? TParams 귀하의 경우와 같은 일부 제한된 시나리오에서

+2

모든 필드를 레코드에 넣고 레코드를 0으로 설정하십시오. 이런 추한 해킹을 사용하지 마십시오. –

+1

Zeroizing은 "관리되는"멤버를 확정하지 않습니다. 숫자 필드 만있는 경우 0으로 설정하면됩니다. –

답변

6

데이비드 헤퍼 넌 이미 말했다 : 당신이하고있는 것은 추악한 해킹하고 매우 깨끗하지는 않습니다. 그것은, 당신은 수행하여 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; 
기록으로 숫자 필드를 켜기 : 그는 또한 힌트를 준

그러면 다음과 같은 결과가 출력됩니다.

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' 등으로 즉시 액세스하십시오. 그러나 모든 필드를 별도로 초기화하는 것만 빼고 (필드가 추가 된 경우 하나만 설정하는 것을 잊을 수는 있지만 몇 개만있는 경우에는 아무 것도 없지만) 레코드 만이 유일한 깨끗한 솔루션입니다. 그리고 일단 최신 버전의 Delphi로 업그레이드 할 수있게되면, ZeroMemory 또는 FillChar 또는 이와 유사한 것보다 더 깨끗한'Default'를 사용하십시오. –

+0

FWIW, FirstValue 및 LastValue처럼 마커 * 바이트 *를 사용하는 대신 두 개의 빈 레코드 ("FirstValue : 레코드 끝;")를 사용할 수있었습니다. ;-)하지만 솔직히, 수녀를 자신의 기록에 넣는 것은 깨끗한 해결책입니다. –

2

(임 델파이 7을 사용)의 InitInstance에 대한 호출이 트릭을 수행해야한다 :

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

'InitInstance'도'정의 된 '필드를'False'로 다시 설정하지 않았습니까? OP는 모든 클래스 필드를 리셋하려고하지 않고 일부만 리셋하려고합니다. – SilverWarior

+2

@ SilverWarior, 그렇습니다. 나는 이것이 필요한지 전혀 모른다. 나는 그 질문의 "모든 분야를 재설정하는 방법"부분만을 언급하고있다. 관리되는 유형의 필드가 있으면 BTW, 또한 실패합니다. –