2009-11-18 8 views
14

Próbuję utworzyć klasę podrzędną TForm zDelphi/Pascal: przeciążenie konstruktora z innego prototypu

  1. specjalnego konstruktora dla pewnych przypadkach i
  2. konstruktor domyślny, który będzie utrzymywać zgodność z aktualnym kodem.

Jest to kod mam teraz:

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; 

wydaje się działać, ale zawsze pojawia się ostrzeżenie kompilatora:

 
[Warning] test.pas(44): Method 'Create' hides virtual method of base type 'TCustomForm' 
  • dodając: "przeciążenie"; po tym, jak drugi konstruktor nie skompiluje się. "[Błąd] test.pas (44): Deklaracja" Utwórz "różni się od poprzedniej deklaracji".
  • tworząc drugi konstruktor kompiluje funkcję klasy bez żadnych błędów ani ostrzeżeń, ale umiera z naruszeniem dostępu w czasie wykonywania (wszystkie pręty członkowskie są zerowe).

Odpowiedz

16

spróbuj dodać reintroduce przed drugim overload, tak:

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; 

To kompiluje w Turbo Delphi. Potrzebowałem public, aby go skompilować, ponieważ przeciążanie metod published jest ograniczone.

+0

bango! Słowo kluczowe "reintrodukuj" jest dokładnie tym, co jest potrzebne. Oryginalny konstruktor jest również potrzebny, ponieważ ustawia zestaw danych na prawidłową wartość domyślną. –

26

Istnieje prosty sposób na uniknięcie tego. Podaj nowy konstruktorowi inną nazwę. W przeciwieństwie do innych popularnych języków, Delphi ma nazwanych konstruktorów; nie musisz ich wywoływać Create. Możesz zadzwonić do nowego CreateWithDataset i nie ingerować w wirtualny konstruktor Create w ogóle.

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; 

W rzeczywistości, o ile nie tworzysz polimorficznie tej klasy, nie potrzebujesz nawet oryginalnego konstruktora. Można zadeklarować swój nowy takiego:

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

Próba wywołać konstruktor jednego argumentu bezpośrednio na TfrmEndoscopistSearch przyniesie błąd kompilacji.


(Tworzenie go polimorficznie będzie na ogół obejmować zastosowanie Application.CreateForm.

Application.CreateForm(TfrmEndoscopistSearch, frmEndoscopistSearch); 

To zawsze wywołuje wirtualną jednego argumentu konstruktora wprowadzony w TComponent O ile nie jest to twój główny formularz, nie trzeba aby to zrobić. pisałem o my feelings on Application.CreateForm wcześniej.)

+0

Jest to prawdopodobnie najbardziej odpowiednie rozwiązanie, ale nie jest to odpowiedź na pytanie.Częścią ćwiczenia jest naprawienie problemu i nie trzeba zmieniać żadnego z pozostałych 10-tych plików, które już używają jednej lub drugiej formy create(). Łączę ten formularz razem z dwóch różnych projektów i nie chcę go rozwidlać. –

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

To powinno załatwić sprawę

Powiązane problemy