Delphiのコンストラクタに関する一連の質問のもう1つ。
仮想コンストラクターを持つ基本クラスがあります。
TComputer = class(TObject)
public
constructor Create(Teapot: Integer); virtual;
end;
コンストラクターは、誰かが呼び出す必要があるときのために仮想です
var
computerClass: class of TComputer;
computer: TComputer;
begin
computer := computerClass.Create(nTeapot);
コンストラクターはoverridden
子孫にあります:
TCellPhone = class(TComputer)
public
constructor Create(Teapot: Integer); override;
end;
TiPhone = class(TCellPhone )
public
constructor Create(Teapot: Integer); override;
end;
WhereTCellPhone
とTiPhone
子孫はそれぞれ独自の初期化を行う機会があります(読みやすさのために含まれていないメンバーの)。
しかし今、私はオーバーロードされたコンストラクターをいくつかの祖先に追加します:
TCellPhone = class(TComputer)
public
constructor Create(Teapot: Integer); override; overload;
constructor Create(Teapot: Integer; Handle: string); overload;
end;
TCellPhoneの代替コンストラクターは、他の仮想コンストラクターを呼び出すため、常に適切なオーバーライド動作を取得します。
constructor TCellPhone.Create(Teapot: Integer; Handle: string);
begin
TCellPhone.Create(Teapot); //call sibling virtual constructor
FHandle := Handle;
end;
問題は、子孫のオーバーライドされたコンストラクターが呼び出されないことです。呼び出しの実際のスタックトレースチェーンは次のとおりです。
phone := TiPhone.Create(37, 'spout')
constructor TCellPhone.Create(Teapot: Integer; Handle: string)
constructor TCellPhone.Create(Teapot: Integer)
constructor TComputer.Create(Teapot: Integer)
TObject.Create
仮想であるへの兄弟呼び出しは、次TCellPhone.Create(int)
の子孫のオーバーライドされたメソッドを呼び出す必要がありますTiPhone
。
phone := TiPhone.Create(37, 'spout')
constructor TCellPhone.Create(Teapot: Integer; Handle: string)
constructor TiPhone.Create(Teapot: Integer)
constructor TCellPhone.Create(Teapot: Integer)
constructor TComputer.Create(Teapot: Integer)
TObject.Create
したがって、兄弟仮想コンストラクターを使用しようとすると、Delphiが期待どおりに機能しないようです。
では、あるコンストラクターが別のコンストラクターを使用するのは悪い考えですか?オーバーロードされたコンストラクターのコードが相互のコピーアンドペーストバージョンであるという設計意図はありますか?
.NETで、いくつかのコンストラクターが相互にチェーンしていることに気付きました。
public Bitmap(int width, int height) : this(width, height, PixelFormat.Format32bppArgb) {}
public Bitmap(int width, int height, PixelFormat format) {...}
これは、次の場合にのみ問題になるようです。
- コンストラクターは仮想です
- コンストラクターをオーバーロードします
あるコンストラクターに別のコンストラクターをオーバーロードさせることはできないというルールはありますか?