2 フェーズの初期化が使用されているのをたくさん見てきました。正当な理由は、2 次コンストラクターから仮想関数を呼び出すことです。ただし、これが必要なユースケースは見たことがありません。いずれかがあります?
3 に答える
例外がサポートされていないプラットフォーム、または例外処理によるコード サイズの増加が受け入れられないプラットフォームでは、2 フェーズの初期化により、失敗する可能性のあるアクティビティをセカンダリ コンストラクターに配置できます。
いいえ、決して避けられません。
最悪の場合、これは単純にビルダー関数 (ランタイム メカニズムによって選択される可能性があります) を呼び出して、オブジェクトのオプションのラッパーを返します。
C++11 では、可動型を使用すると、動的割り当ての必要さえなく、単純に a を返すだけboost::optional<T>
で十分です。
もちろん、コンストラクターの直接呼び出しからビルダー関数/ファクトリーの呼び出しに変わります。しかし、いつでも 2 フェーズの初期化よりも負担が増えることを好みます。そのように部分オブジェクトを取得できないからです!
C++ コンストラクターでは実行できない、他の言語のコンストラクターから呼び出される仮想関数を見た 1 つの方法は次のとおりです。
class AController
{
};
class A
{
private:
// This is only a raw pointer that never gets freed for simplicity
// The real code does ensure it gets freed when appropriate
AController *controller;
protected:
virtual AController *CreateController()
{
return new AController();
}
public:
A()
{
controller = CreateController();
}
};
class BController : public AController
{
};
class B : public A
{
protected:
virtual AController *CreateController()
{
return new BController();
}
};
A
は複雑なオブジェクトであり、いくつかの のController
ようなサブオブジェクト (ここでは 1 つだけ含めました) を持ち、それぞれ (適切な場合) から独立して派生させることができます。C++ では、CreateController
コンストラクターが終了した後に -like 関数を呼び出す必要があります。そうしないと、BController
-like オブジェクトが作成されません。
Initialize()
メソッドを明示的に呼び出す必要を回避することは可能ですが、Initialize()
メソッド ( も実行するヘルパー関数から呼び出されるnew A()
) は、より簡単な方法の 1 つです。