2012-02-14 16 views
6

私はちょうど簡単な質問をしたかった - 私は次のようにTLabelから派生したクラスを持っている:今、Delphiは私がオーバーライドととせずに両方のバージョンをコンパイルすることができますオーバーライドと非上書きコンストラクタ

TMyLabel = class (TLabel) 
    ... 
    constructor Create(AOwner: TComponent); override; 
end; 

constructor TMyLabel.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    { some code } 
end; 

を。違いが何であるか説明できますか? に上書きされたときにCreate()に自分のパラメータを要求できないこと以外ありがとう

編集:私が言っているのは、virtualと非仮想ベースの子孫コンストラクタの違いは何ですか?私は常に継承されたコンストラクタをinherited Create()で呼び出すことができるので、何がポイントですか?

+0

[派生クラスでコンストラクタ宣言の後にオーバーロードまたはオーバーライドする必要がありますか?](http://stackoverflow.com/questions/360597/need-i-put-overload-or-override)コンストラクタ宣言の後の言葉) –

+0

コンパイラは、そうしないと警告を出しますが、そうですか?リンクされた複製から"そうしないと、TMinMatrixのコンストラクタがTMatrixのコンストラクタを「隠している」とコンパイラが警告するでしょう。 - コンポーネントコンストラクタを非表示にするための実用的なNEEDはまだありません。特に、TCOmponentはコンストラクタとデストラクタの適切な仮想動作に依存しているようです。一般に、TComponentでは実際にはエラーに近いものです。 –

+0

はい、そうです。それは、それが_子孫ではないという意味で「隠している」かもしれませんが、私がそれを '継承された'によって呼び出すので、それは何か違いはありますか? –

答えて

9

仮想コンストラクタでは、オブジェクトの多態的なインスタンス化が可能です。これの古典的な例は、Delphiの.dfmストリーミングメカニズムです。

.dfmファイルを読み込んでフォームをインスタンス化するコードは、コンパイル時にどのクラスを使用するか分かりません。決定は、実行可能になるまで、すなわち.dfmファイルが読み込まれたときに延期される。さらに、.dfmファイルメカニズムを使用して、VCLの一部ではないカスタムコンポーネントを作成することができます。したがって、この.dfmメカニズムは、VCLの一部ではないクラスを正しくインスタンス化できなければなりません。

TComponentのコンストラクタは次のように宣言されている:それはoverrideディレクティブとそのコンストラクタを宣言する必要があり、このメカニズムに参加するコンポーネントについて

constructor Create(AOwner: TComponent); virtual; 

プロセスのもう1つのキーはクラス参照です。例

type 
    TComponentClass = class of TComponent; 

について.DFMファイルを読み込むときにコンポーネントを作成するコードは、大体、次のようになります。

var 
    ComponentClass: TComponentClass; 
    Component, Owner: TComponent; 
.... 
ComponentClass = FindComponentClass(ReadComponentClassName); 
Component := ComponentClass.Create(Owner); 

、メカニズムはそれから呼び出されることになるコンストラクタを仮想コンストラクタを使用しなかった場合TComponent.Createとなります。したがって、コンストラクタTMyLabel.Createは決して呼び出されません。

これは、TComponentから派生するときに、コンストラクタにoverrideディレクティブを含める必要があるためです。

+0

ありがとうございます。しかし、私は 'TMyLabel'をさらに派生させたいと思っていましたが、作成時にもっと多くのパラメータを指定したかったのですが、それはまったく可能でしょうか? –

+0

@MartinMelkaこれは、.dfmメカニズムでラベルをインスタンス化する場合には不可能です。これは常に単一のパラメータで仮想コンストラクタを呼び出すことになります。おそらく、そのコンストラクタと一緒に行って、メソッドまたはプロパティを追加して、余分なパラメータが作成後に提供されるようにするだけです。 –

+0

私はそう考えていました。 –

2

もし、コンストラクタがオーバーライドされると、クラスリファレンス(例としてthis specを参照)を使って呼び出すことができるでしょう。

+0

オーバーライドされた仮想コンストラクタは、コンストラクタが最初に宣言された基本クラスのみを認識するクラスファクトリによって呼び出されることがあります。 –

関連する問題