2009-11-18 5 views
14

Je suis en train de créer une classe d'enfants de TForm avecDelphi/pascals: la surcharge d'un constructeur avec un autre prototype

  1. un constructeur spécial pour certains cas, et
  2. un constructeur par défaut qui maintiendra la compatibilité avec le code actuel.

Ceci est le code que j'ai maintenant:

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; 

Il semble fonctionner, mais je reçois toujours l'avertissement du compilateur:

 
[Warning] test.pas(44): Method 'Create' hides virtual method of base type 'TCustomForm' 
  • Ajout "surcharge;" après le deuxième constructeur ne compilera pas. "[Error] test.pas (44): La déclaration de 'Create' diffère de la déclaration précédente".
  • faisant le deuxième constructeur une fonction de classe compile sans erreurs ou avertissements, mais meurt avec une violation d'accès à l'exécution (toutes les variables membres sont nulles).

Répondre

16

Essayez d'ajouter reintroduce avant la deuxième overload, comme ceci:

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; 

Cette compile dans Turbo Delphi. J'avais besoin du public pour le compiler car la surcharge des méthodes published est restreinte.

+0

bango! Le mot clé "reintroduce" est exactement ce dont vous avez besoin. Le constructeur d'origine est également nécessaire car il définit l'ensemble de données sur la valeur par défaut appropriée. –

26

Il existe un moyen très simple d'éviter cela. Attribuez un autre nom à votre nouveau constructeur. Contrairement à d'autres langages populaires, Delphi a constructeurs nommés; vous n'avez pas à les appeler Créer. Vous pouvez appeler votre nouveau CreateWithDataset et ne pas interférer avec le constructeur Create virtuel du tout. En fait, à moins d'instancier cette classe de manière polymorphique, vous n'avez même pas besoin du constructeur d'origine. Vous pouvez déclarer votre nouveau comme ceci:

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

Tentative d'appeler le constructeur à un argument directement sur TfrmEndoscopistSearch produirait une erreur de compilation.


(création il serait généralement polymorphically impliquer l'utilisation Application.CreateForm:.

Application.CreateForm(TfrmEndoscopistSearch, frmEndoscopistSearch); 

qui appelle toujours le constructeur virtuel un argument introduit dans TComponent moins que ce soit votre principale forme, vous n'avez pas besoin de le faire. Je l'ai écrit sur my feelings on Application.CreateForm avant.)

+0

C'est probablement la solution la plus appropriée, mais ce n'est pas la réponse à la question.Une partie de l'exercice consiste à corriger le problème et à ne pas avoir à changer l'un des 10 autres fichiers qui utilisent déjà l'une ou l'autre forme de create(). Je fusionne ce formulaire à partir de deux projets différents et je ne voulais pas le fourrer. –

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

Cela devrait faire l'affaire

Questions connexes