2011-07-11 18 views
7

これはおそらく簡単な質問ですが、クラスのコンストラクタが確実に呼び出されるようにする方法を知りたいと思います。Delphi - クラスコンストラクタが呼び出されていることを確認する

私は次のコードをお持ちの場合:

type TMyObject = class(TObject) 
    public 
    constructor Create;override; 
end; 

implementation 

constructor TMyObject.Create;override; 
begin 
    inherited; 
    //do other instantiation 
end; 

をDelphiは、これを許可していません - 「静的メソッドをオーバーライドすることはできません」。

私は、オブジェクトが私のカスタムCreateコンストラクタを使用して作成され、祖先Createコンストラクタの呼び出しを禁止していることを確認します。

constructor Create(aName : String);overload; 

が、プログラマは、潜在的祖先は()メソッドを作成して呼び出すことができます。

問題への私の現在のソリューションはこれのように一意に作成signaturedコンストラクタを定義することです。

+0

おかげで静的メソッド、まだ破壊は仮想ですか?また、AfterConstruction、またはCreateを使用して、どのような方法がありますか? – Simon

+0

あなたはそれについて別の質問をしたいと思うかもしれません。それはコメントの中で答えが「あまりにも多い」ものなのですから... –

+0

私はとにかく試してみます - 任意のクラスを持つオブジェクトを作成するよりも、任意のクラス(例えば 'OwnsObject:= True'で' TObjectList')上でデストラクタを呼び出すほうがはるかに可能です。 –

答えて

14

祖先の名前を持つコンストラクタを単純に再導入します。いったんこれを実行すると、に導入されたコンストラクタを呼び出すTMyObjectを作成する方法はありません。あなたはこのようなコードを使用する場合:祖先のコンストラクタが仮想ではないので

TMyObject = class 
public 
    constructor Create; 
end; 

constructor TMyObject.Create; 
begin 
    // I am not calling the inherited constructor because 
    // I do not want to. 
end; 

あなたはTMyObject.Createoverride修飾子を使用しないでください。

このスキームを使用すると、祖先で導入されたコンストラクタを使用してTMyObjectを作成することはできません。この場合、祖先はTObjectであり、唯一のコンストラクタはTObject.Createです。ユーザーはこのコードを書き込んだ場合:

X := TMyObject.Create; 

それはかなり明白だ、TMyObjectのコンストラクタはTObjectに導入された1つ、ないと呼ばれます。


あなたが恐れて、ユーザーが祖先のコンストラクタを使用してクラスを作成するためにフープを介してジャンプしまうなら、あなたはAfterConstruction方法から自分のものを行うことができます。それは仮想メソッドですので、それはあなたのオブジェクトが先祖のタイプのクラス参照を使用して作成された場合でも呼び出されます:

TMyObject = class 
public 
    procedure AfterConstruction;override; 
end; 
+0

数秒で私を打つ! –

+0

そんなにシンプルなので、私はあまりにもそれを読んでいたと思う! AfterConstructionの場合は – Simon

+1

+1。 didntはこれが利用可能であったことを知っています。 – Simon

6

TObject.Createが仮想コンストラクタ、それゆえエラーではありません。

"他のプログラマー"が先祖Createメソッドを呼び出すことができる方法は、故意にいくつかのフープをジャンプすることです。非表示になり、新たに導入されたコンストラクタとして

var 
    ClassRef: TClass; 
    Obj : TObject; 
begin 
    ClassRef := TMyObject; 
    Obj := ClassRef.Create; 
end; 

TObject.Create

は何がしたいことは、より似おそらく非仮想:、作成何らかの理由がある答えを

type TMyObject = class(TObject) 
    public 
    constructor Create;virtual; 
end; 

implementation 

constructor TMyObject.Create; 
begin 
    inherited; 
    //do other instantiation 
end; 
+0

+1の説明です。 –

+0

これは間違っています。実装セクションで「オーバーライド」を省略します。 –

+0

@Rudy - 井戸が見つかる。一定! –

関連する問題