2009-04-21 3 views
21

TObjectまたはTPersistentから派生したクラスのコンストラクタで "継承"を呼び出す必要がありますか?TObjectの "Create"コンストラクタで継承を使用する

constructor TMyObject.Create; 
begin 
inherited Create; // Delphi doc: Do not create instances of TPersistent. Use TPersistent as a base class when declaring objects that are not components, but that need to be saved to a stream or have their properties assigned to other objects.  
VectorNames := TStringList.Create; 
Clear; 
end; 

答えて

38

はい。それは何もしませんが、それは無害です。実際に継承されたコンストラクタを常に呼び出すことについては、実際に実装されているかどうかを確認せずに一貫しているという価値があると思います。 Embarcaderoが今後TObject.Createの実装を追加する可能性があるため、継承されたCreateを呼び出す価値があると言う人もいますが、これは真実ではありません。それは、継承されたCreateを呼び出さない既存のコードを破壊するでしょう。それでも、それだけで一貫性の理由から呼び出すことは良い考えだと思います。

+0

確かに、それは良い習慣です –

+0

"それは何もありません" ??これは、基本的なオブジェクトのストレージを開始します!また、継承している基本クラスで必要なものを定義することもできます。それを呼び出さないと、最悪の種類のエラーやバグが発生する可能性があります。 –

+2

IIRCでは、基本ストレージはコンストラクター(Create)が呼び出される前に既に割り当てられています。 – mj2008

13

私はいつもこれを行います。

あなたがリファクタリングと共通の祖先にコードを移動し、継承を呼び出す場合の作成には、次のような利点があります

  1. 共通の祖先がコンストラクタを持っている場合、あなたはそれを呼び出すことを忘れることはできません。
  2. 共通の祖先に異なるパラメータを持つコンストラクタがある場合、コンパイラはこれを警告します。
+3

Craigはすぐにオフコースですが、これらも私が主に継承したCreate、一貫性のあるものよりも多くのこと –

2

「プロシージャAfterConstruction」をオーバーライドすることもできます。どのようなコンストラクタであっても、このプロシージャは常に呼び出されます。

public 
    procedure AfterConstruction; override; 
end; 

procedure TfrmListBase.AfterConstruction; 
begin 
    inherited; 
    //your stuff, always initialized, no matter what kind of constructor! 
end; 

たとえば:あなたは、このようなTComponent.Create(AOwner)またはカスタム(オーバーロード)コンストラクタとして通常TObject.Createとは異なるコンストラクタを持つオブジェクトを作成したい場合は、問題を得ることができますので、あなたのオーバーライドが呼び出されず、(この場合) "VectorNames"変数はゼロになります。

+3

オーバーライドされたコンストラクタが呼び出されない場合、それは子孫クラスのバグです。それは子孫クラスの開発者が心配するのではなく、あなたを呼び出すことはできません。 –

+2

Rob:TObject子孫を生成するファクトリクラスを作成する場合、TObject.Createを使用することはできません。 ()これは仮想ではないためです:あなたが工場でTComponent子孫を作るなら、それは別のコンストラクタ(Create(AOwner))を持っています。あなたはAfterConstructionを使うべきです:コンストラクタの種類に関係なく常に呼び出されます –

2

非常に最適化されたコンストラクタが必要な場合を除いて、私はそれを呼び出します。

関連する問題