명시적인 호출이 없는 경우 재정의된 프로시저에서 Delphi 호출이 상속됩니까?

StackOverflow https://stackoverflow.com/questions/53715

  •  09-06-2019
  •  | 
  •  

문제

코드에 명시적인 호출이 없으면(상속됨), 다음과 같은 구조를 갖습니다(슈퍼 클래스에서 하위 클래스로).

TForm >> TBaseForm >> TAnyOtherForm

프로젝트의 모든 양식은 TBaseForm에서 파생됩니다. 이는 모든 양식(보안, 유효성 검사 등)에 사용되는 모든 표준 설정 및 파괴적인 부분을 갖기 때문입니다.

TBaseForm에는 이 작업을 수행하는 코드와 함께 onCreate 및 onDestroy 프로시저가 있지만 누군가(예: 나)가 TAnyOtherForm의 onCreate에 상속된 항목을 추가하는 것을 잊어버린 경우 Delphi가 나를 위해 이를 호출합니까?웹에서 필요하지 않다는 참조를 찾았지만 코드에서 생략된 경우 호출되는지 여부는 어디에도 나와 있지 않습니다.

또한 상속된 호출이 있는 경우 언제 호출됩니까?

도움이 되었습니까?

해결책

아니요, 상속된 호출을 그대로 두면 호출되지 않습니다.그렇지 않으면 메서드를 재정의하고 해당 메서드의 상위 버전을 완전히 생략하는 것이 불가능합니다.

다른 팁

개체 삭제 시 상속을 호출하지 않으면 메모리 누수가 발생할 수 있다는 점은 언급할 가치가 있습니다.소스 코드에서 이를 확인할 수 있는 도구가 있습니다.

상속된 호출은 명시적으로 이루어져야 합니다.일반적으로 동등한 상황에서 상속된 함수를 자동으로 호출하는 언어는 없습니다(클래스 생성자는 포함되지 않음).

클래스 생성자에서 상속된 호출을 수행하는 것을 잊어버리기 쉽습니다.이러한 상황에서 기본 클래스가 데이터를 초기화해야 하는 경우 액세스 위반이 발생하기를 기다리고 있습니다.

아마도 TBaseForm 클래스에서 DoCreate 및 DoDestory를 재정의하여 하위 클래스의 구현에 관계없이 일부 코드가 실행되도록 할 수 있습니다.

// interface

TBaseForm = Class(TForm)
...
Protected
    Procedure DoCreate(Sender : TObject); Override;
End

// implementation

Procedure TBaseForm.DoCreate(Sender : TObject);
Begin
    // do work here

    // let parent call the OnCreate property  
    Inherited DoCreate(Sender);
End;

Inherited는 시각적 양식 상속뿐만 아니라 하위 개체에서도 명시적으로 호출되어야 합니다.클래스 완성을 사용하는 경우 정의에 재정의 플래그를 지정하면 상속이 자동으로 추가됩니다(재도입용은 아님).시각적 양식 상속을 사용하는 경우 양식 편집기를 통해 새 이벤트 처리기를 추가하면 상속도 추가됩니다.

상속된 코드는 다른 코드에서 지적한 것처럼 암시적으로 호출되지 않습니다.명시적으로 호출해야 합니다.이는 유용한 유연성을 제공합니다.예를 들어, 상속된 코드 이전에 전처리 코드를 수행한 다음 나중에 후처리 코드를 수행할 수 있습니다.이는 다음과 같을 수 있습니다:

procedure TMyCalcObject.SolveForX;
begin
  ResetCalcState;
  inherited SolveForX;
  PostProcessSolveForX;
end;

아니요.이것이 재정의의 요점입니다.

명시적으로 호출해야 합니다.상속된 메서드를 호출할 코드 지점을 선택할 수 있으므로 유연성이 뛰어납니다.하지만 이는 버그의 큰 원인이기도 합니다.상속된 함수를 호출하는 것을 잊어버리기 쉽고 컴파일러는 의도적으로 호출했는지 아니면 방금 잊어버렸는지 알 수 있는 방법이 없습니다.

상속된 메소드를 호출하고 싶지 않다는 것을 컴파일러에 알리는 일종의 "skip_inherited" 지시문이 있어야 합니다.

그러면 컴파일러는 "inherited" 또는 "skip_inherited"를 찾지 못한 경우 쉽게 오류를 보고합니다.그것은 당신이 잊었다는 것을 의미합니다.그러나 불행하게도 CodeGear의 어느 누구도 그런 생각을 하지 않았습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top