バックグラウンド:
私が解決する必要がある同様の状況については、C++ FAQ のこの質問を参照してください。
私は基本クラスを持っていclass Bます。
関数、メンバー、および追加のメモリ割り当てを介して追加機能を追加するclass DB からの派生クラスがあります。
class B追加機能は、何もしないかデフォルト値を返すことによって、および にnullptrs固有の仮想関数からポリモーフィックにサポートされますclass D。
class Bpublic 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 ABclass Bclass 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返されることがわかっている固有の仮想メソッドを使用します。nullptrclass B
if(getB()->VirtualMethodSpecificToClassD() == nullptr) {
//Call B::CreateB(...)
} else {
//Call D::CreateD(...)
}
3 つのケースすべてにコードの匂いがあります。
- 「else-if-heimers」を引き起こします。
- これが実際に機能するかどうかはわかりません。
- 「実装ではなくインターフェースへのコード」のグッドプラクティスに違反しています。