ここでかなり基本的な概念が欠けている場合は申し訳ありませんが、複数のクラス型 (すべて同じ親から派生) のコレクションを維持し、それらを取得するときにサブクラス固有のメソッドにアクセスできるようにする方法を見つけようとしています。コレクションから。
コンテキストとして、1 つの基本クラス (「BaseClass」) と、この基本クラスからすべて派生した多数のクラス (「SubClassA」から「SubClassZ」など) があります。また、作成したすべての SubClass オブジェクトの中央インデックス付きコレクションを維持する必要があります。
typedef unordered_map<std::string, BaseClass*> ItemCollectionType;
ItemCollectionType Items;
リストには SubClass オブジェクトのみが含まれますが、リストのメンバー型を「BaseClass」ポインターとして定義して、任意のサブクラスのインスタンスを格納できるようにしました。これまでのところ、このアプローチには特に悪い点はないと思います (ただし、間違っている場合は訂正してください)。
私が抱えている問題は、これらのコレクションとそのコンテンツのコピーを作成する必要がある場合があることです。このための(簡略化された)コードは次のとおりです。
ItemCollectionType CopiedItems;
ItemCollectionType::const_iterator it_end = Items.end();
for (ItemCollectionType::const_iterator it = Items.begin(); it != it_end; ++it)
{
BaseClass *src = it->second;
BaseClass *item = new BaseClass(src);
NewItems[item->code] = item;
}
ここでの明らかな問題は、コンパイラが "src" が実際に指している SubClass のコピー コンストラクターではなく、BaseClass のコピー コンストラクターのみを呼び出すことです。
このような状況で推奨されるアプローチは何ですか? タイプ BaseClass のコレクションに追加することによって、このサブクラス タイプ情報を「失う」状況に陥る必要がありますか? コレクションを維持する他の方法は見当たりませんが、より良い代替手段があれば教えてください。
各 SubClass オブジェクトには、サブクラスのフレーバーを示す数値 ID が含まれています。その結果、この数値 ID を「型」オブジェクトに変換する関数を作成し、それを使用してコピー コンストラクターを呼び出す前にソース オブジェクトをキャストすることは可能ですか? これはテンプレート化の有効な用途ですか?
もちろん、これはひどいプログラミング手法であったり、不可能であったりする可能性があります。私は、最も単純で保守性の低いソリューションよりも優れたオプションがあるはずだと確信しています
switch (src->code)
{
case SubClassTypes::VarietyA:
SubClassA *item = new SubClassA( *((SubClassA*)src) );
Items[item->code] = item;
break;
case SubClassTypes::VarietyB:
SubClassB *item = new SubClassB( *((SubClassB*)src) );
Items[item->code] = item;
break;
...
...
}