バックグラウンド:
私が解決する必要がある同様の状況については、C++ FAQ のこの質問を参照してください。
私は基本クラスを持っていclass B
ます。
関数、メンバー、および追加のメモリ割り当てを介して追加機能を追加するclass D
B からの派生クラスがあります。
class B
追加機能は、何もしないかデフォルト値を返すことによって、および にnullptrs
固有の仮想関数からポリモーフィックにサポートされますclass D
。
class B
public static Factory Methods
すべての建設に使用しますprotected constructors
。(参照:名前付きコンストラクタイディオム)
class D
クラス B とは異なる名前が付けられ、クラス B では使用できないpublic static Factory Methods
すべての構成に使用します。protected constructors
しばらくして、新しいインターフェイス クラスが作成されclass A
ます。このクラスには、派生クラスがclass A
ゲッター関数とセッター関数の両方を必要とするようなインターフェースがありますpointer to a class B
が、動的な値はまたはのいずれclass B
かになります。class D
質問:
class A
のコピー コンストラクター、代入演算子、および/またはセッターを派生させて作成したいのですが、はそのメンバーを型のオブジェクトとしてのみ公開するclass B
ため、返されたオブジェクトがまたはであるかどうかを判断する方法がありません。class A
B
class B
class D
スライスやメモリの問題を引き起こすことなく、パブリックインターフェイスのみを使用して上記を正しく実装するにはどうすればよいですか (上記の設定が間違っていて変更する必要がある場合を含む)。
可能な解決策?:
いくつかのオプションを試してみたくなりました:
1) クラス B にメンバーを作成し、オブジェクトの型を宣言するすべての派生型を作成します。
if(getB()->GetType() == "D") {
//Call D::CreateD(...)
} else if(getB()->GetType() == "B") {
//Call B::CreateB(...)
}
2) 派生型に動的にキャストし、失敗をチェックします。
if(dynamic_cast<D*>(getB()) == nullptr) {
//Call B::CreateB(...)
} else {
//Call D::CreateD(...)
}
3)オブジェクトで使用するとclass D
返されることがわかっている固有の仮想メソッドを使用します。nullptr
class B
if(getB()->VirtualMethodSpecificToClassD() == nullptr) {
//Call B::CreateB(...)
} else {
//Call D::CreateD(...)
}
3 つのケースすべてにコードの匂いがあります。
- 「else-if-heimers」を引き起こします。
- これが実際に機能するかどうかはわかりません。
- 「実装ではなくインターフェースへのコード」のグッドプラクティスに違反しています。