2

カスタム コンストラクターを持つ BaseForm から派生した MainForm が必要です。これは Mainform であるため、*.dpr ファイルでApplication.CreateForm(TMyMainForm, MyMainForm)を呼び出すことによって作成されます。ただし、フォームの作成中にカスタム コンストラクターが呼び出されません。

MyMainForm := TMyMainForm.Create(AOwner)を呼び出すと、明らかに正常に動作します。カスタム コンストラクターを持つフォームをメイン フォームとして使用することはできませんか?

TBaseForm = class(TForm)
  constructor Create(AOwner:TComponent; AName:string);reintroduce;
end;

TMyMainForm = class(TBaseForm)
  constructor Create(AOwner:TComponent);reintroduce;
end;  

constructor TBaseForm.Create(AOwner:TComponent);

begin;
  inherited Create(AOwner);
end;

constructor TMyMainForm.Create(AOwner:TComponent);

begin;
  inherited Create(AOwner, 'Custom Constructor Parameter');
end;  
4

2 に答える 2

8

Application.CreateForm()reintroduce'd コンストラクターを呼び出すことはできません。新しいオブジェクトを作成するとき、コンストラクターを呼び出し、TComponent.Create()ポリモーフィズムが派生コンストラクターを呼び出すことを期待します。reintroduceカスタム コンストラクターを 'ing することにより、ポリモーフィック コール チェーンの一部ではなくなります。reintroduce継承されたメソッドと同じ名前を持つが、それとは関係のない、まったく新しいメソッドを公開します。

試みていることを行うにはreintroduce、コンストラクターに使用しないでください。Base フォームに別のコンストラクターを作成し、次に MainFormoverrideを標準コンストラクターにして、カスタム Base コンストラクターを呼び出します。

TBaseForm = class(TForm)
  constructor CreateWithName(AOwner: TComponent; AName: string); // <-- no reintroduce needed since it is a new name
end;

TMyMainForm = class(TBaseForm)
  constructor Create(AOwner: TComponent); override; // <-- not reintroduce
end;  

constructor TBaseForm.CreateWithName(AOwner: TComponent; AName: string);
begin;
  inherited Create(AOwner);
  // use AName as needed...
end;

constructor TMyMainForm.Create(AOwner: TComponent);
begin;
  inherited CreateWithName(AOwner, 'Custom Constructor Parameter');
end;  
于 2014-10-01T02:30:40.160 に答える
2

フォームを VCL メイン フォームにするためには、 への呼び出しを介してフォームを作成する必要がありますApplication.CreateForm。次に、 で宣言された仮想コンストラクターを呼び出しますTComponent。そのため、VCL メイン フォームに対して別のコンストラクターを呼び出す方法はありません。

1 つのオプションは、Remy によって提示されたものです。で宣言されたコンストラクターをオーバーライドし、TComponent追加のパラメーターを渡して別のコンストラクターを呼び出す。これは、同じクラスのコンストラクター、または基本クラスから継承されたコンストラクターです。

ここでの別のオプションは、基本クラスで抽象クラス メソッドを使用することです。例えば、

type
  TMainFormBase = class(TForm)
  protected
    class function ProjectName: string; virtual; abstract;
    class function RegKeyPath: string; virtual; abstract;
  end;

派生クラスでは、これらの抽象メソッドをオーバーライドします。コンストラクターでプロパティを設定する代わりに、基本フォーム クラスのコードでこれらのメソッドを呼び出すことができます。もちろん、コンストラクターで作業を行う必要がある場合は、コンストラクターからこれらのメソッドを完全に呼び出すことができます。

個人的には、既に仮想コンストラクターを持つクラスに新しいコンストラクターを追加することに偏見があります。仮想コンストラクター パラダイムは、その単一の仮想コンストラクターのみを使用する方向に導きます。階層のさらに下にさまざまなコンストラクターを追加し始めると、仮想的にインスタンス化するときに間違ったコンストラクターが呼び出されることによって引き起こされる問題が発生しやすくなります。

于 2014-10-02T10:01:31.257 に答える