2009-11-18 4 views
14

Ich versuche, ein Kind Klasse von TForm mitDelphi/pascal: ein Konstruktor mit einem anderen Prototyp Überlastung

  1. einen speziellen Konstruktor für bestimmte Fälle zu schaffen, und
  2. ein Standard-Konstruktor, die Kompatibilität beibehalten wird mit dem aktuellen Code.

Dies ist der Code Ich habe jetzt:

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; 

Es scheint, zu arbeiten, aber ich bekomme immer die Compiler-Warnung:

 
[Warning] test.pas(44): Method 'Create' hides virtual method of base type 'TCustomForm' 
  • Hinzufügen "Überlast"; nach dem zweiten Konstruktor wird nicht kompiliert. "[Error] test.pas (44): Die Deklaration von 'Create' unterscheidet sich von der vorherigen Deklaration".
  • war der zweite Konstruktor eine Klasse Funktion ohne Fehler oder Warnungen kompiliert, aber stirbt mit einer Zugriffsverletzung zur Laufzeit (alle Mitglied Vars sind null).

Antwort

16

Try reintroduce vor dem zweiten overload, wie das Hinzufügen von:

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; 

Dies kompiliert in Turbo Delphi. Ich brauchte die public, um es zu kompilieren, weil die Überladung von published Methoden beschränkt ist.

+0

bango! Das Schlüsselwort "Wiedereinführung" ist genau das, was benötigt wird. Der ursprüngliche Konstruktor wird ebenfalls benötigt, da er den Datensatz auf den richtigen Standardwert setzt. –

26

Es ist eine wirklich einfache Möglichkeit, dies zu vermeiden. Geben Sie Ihrem neuen Konstruktor einen anderen Namen. Im Gegensatz zu anderen populären Sprachen hat Delphi benannte Konstruktoren; Sie müssen sie nicht Create nennen. Sie könnten Ihr neues CreateWithDataset aufrufen und den virtuellen Create-Konstruktor überhaupt nicht stören.

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; 

Tatsächlich, wenn Sie diese Klasse nicht polymorphisch instanziieren, benötigen Sie nicht einmal den ursprünglichen Konstruktor.

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

Der Versuch, rufen Sie das ein Argument Konstruktor direkt auf TfrmEndoscopistSearch ergäbe einen Kompilierungsfehler: Sie könnten Ihre neue wie folgt erklären.


(es polymorph Erstellen der Regel mit Application.CreateForm verbunden wäre.

Application.CreateForm(TfrmEndoscopistSearch, frmEndoscopistSearch); 

, die immer den virtuellen Konstruktor ein Argument in TComponent eingeführt nennt, wenn diese die wichtigste Form ist, brauchen Sie nicht das zu tun. ich my feelings on Application.CreateForm über geschrieben habe vor.)

+0

Dies ist wahrscheinlich die am besten geeignete Lösung, aber es ist nicht die Antwort auf die Frage.Ein Teil der Übung besteht darin, das Problem zu beheben und keine der anderen 10-er-Dateien zu ändern, die bereits die eine oder andere Form von create() verwenden. Ich fasse dieses Formular aus zwei verschiedenen Projekten zusammen und wollte es nicht abzweigen. –

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

Dies sollte den Trick

tun
Verwandte Themen