2009-11-18 5 views
14
내가

델파이/파스칼 : 다른 프로토 타입과 생성자를 오버로드

  1. 으로 어떤 경우를위한 특별한 생성자를 TForm 클래스의 하위 클래스를 만들려고 해요

  2. 호환성을 유지하는 기본 생성자 현재 코드.

    interface 
        TfrmEndoscopistSearch = class(TForm) 
        public 
        /// original constructor kept for compatibility 
        constructor Create(AOwner : TComponent); overload; override; 
        /// additional constructor allows for a caller-defined base data set 
        constructor Create(AOwner : TComponent; ADataSet : TDataSet; ACaption : string = ''); overload; 
        end; 
    

    그것은 작동하는 것 같다,하지만 난 항상 컴파일러 경고 얻을 :

이 내가 지금 가지고있는 코드입니다

 
[Warning] test.pas(44): Method 'Create' hides virtual method of base type 'TCustomForm' 
  • 추가 "과부하;" 두 번째 생성자는 컴파일되지 않습니다. "[Error] test.pas (44) : 'Create'선언은 이전 선언과 다릅니다."
  • 두 번째 생성자를 오류 또는 경고없이 컴파일하지만 런타임에 액세스 위반으로 종료됩니다 (모든 멤버 변수는 nil 임). 다음과 같이 두 번째 overload 전에 reintroduce를 추가

답변

16

봅니다 :

TfrmEndoscopistSearch = class(TForm) 
    public 
    /// original constructor kept for compatibility 
    constructor Create(AOwner : TComponent); overload; override; 
    /// additional constructor allows for a caller-defined base data set 
    constructor Create(AOwner : TComponent; ADataSet : TDataSet; ACaption : string = ''); reintroduce; overload; 
    end; 

이 터보 델파이로 컴파일합니다. published 메서드의 오버로드가 제한되어 있기 때문에 컴파일하기 위해 public이 필요했습니다.

+0

bango! "reintroduce"키워드는 정확히 필요한 것입니다. 원래의 생성자는 데이터 세트를 적절한 기본값으로 설정하기 때문에 필요합니다. –

26

이 문제를 피하는 쉬운 방법이 있습니다. 새 생성자에 다른 이름을 지정하십시오. 다른 인기있는 언어와 달리 Delphi에는 이라는 이름의 생성자가 있습니다.; Create라고 부를 필요는 없습니다. 새 CreateWithDataset을 호출하고 가상 Create 생성자를 전혀 간섭하지 않을 수 있습니다.

TfrmEndoscopistSearch = class(TForm) 
    /// original constructor kept for compatibility 
    constructor Create(AOwner: TComponent); override; 
    /// additional constructor allows for a caller-defined base data set 
    constructor CreateWithDataset(AOwner: TComponent; ADataSet: TDataSet; ACaption: string = ''); 
end; 

실제로이 클래스를 다형 적으로 인스턴스화하지 않으면 원래 생성자가 필요하지 않습니다. 컴파일 오류를 얻을 것입니다 직접 TfrmEndoscopistSearch에 하나의 인수 생성자를 호출하려고

TfrmEndoscopistSearch = class(TForm) 
    /// additional constructor allows for a caller-defined base data set 
    constructor Create(AOwner: TComponent; ADataSet: TDataSet; ACaption: string = ''); reintroduce; 
end; 

:이 같은 새로운 하나를 선언 할 수 있습니다.


(일반적으로 Application.CreateForm 사용하여 포함 할 다형을 만들기. 그것은 당신의 기본 양식 아니라면 항상 TComponent의에서 소개 한 인수 가상 생성자를 호출

Application.CreateForm(TfrmEndoscopistSearch, frmEndoscopistSearch); 

, 당신은 필요가 없습니다 그렇게. 내가 전에 대한 my feelings on Application.CreateForm를 작성했습니다.)

+0

이것은 아마도 가장 적합한 해결책 일 수 있지만 질문에 대한 대답이 아닙니다.연습의 일부는 문제를 수정하고 다른 형식의 create()를 이미 사용하는 다른 10 개 또는 그 이상의 파일을 변경하지 않아도되는 것입니다. 두 개의 서로 다른 프로젝트에서이 양식을 병합 중이며 포크로 만들고 싶지 않습니다. –

6
constructor Create(AOwner:Tcomponent;str:string);overload; 
... 
constructor TfrmEndoscopistSearch.Create(AOwner: Tcomponent; str: string); 
    begin 
    inherited Create(AOwner); 
    showmessage(str); 
    end; 

를이 트릭을 할해야

,536,
관련 문제