データメンバーのみを含む(関数を含まない)クラスを作成しようとしていますが、それらを多態的にしたいと思います。つまり、基本クラスへのポインターによってオブジェクトを渡すことになり、次の機能が必要になります。それらを特定の派生型に変換します(インスタンスが指定された型でない場合dynamic_cast
、結果の値はになります)。NULL
例として、私はアイテムを持っています:
struct Item {
int x, y;
}
動くアイテムと、テキストを含むアイテムもあります。
struct MovingItem: virtual public Item {
int speedX, speedY;
}
struct TextItem: virtual public Item {
std::string text;
}
おそらく、上記の仮想継承を使用する必要があります。これは、移動してテキストを含むアイテムも必要なためですが、トップレベルからの1セットの座標のみが必要ですItem
。
struct MovingTextItem: virtual public MovingItem, virtual public TextItem {
}
これらはすべて正しく定義できますが、それがどのタイプであるかを確認しようとdynamic_cast
すると、コンパイラはソースタイプがポリモーフィックではないと文句を言います。Item *
void example(Item *i) {
MovingTextItem *mti = dynamic_cast<MovingTextItem *>(i); // error!
}
これは、データメンバーの代わりに仮想関数を使用してすべてを再実装した場合に機能しますが、何もオーバーライドする必要がないため、これは無駄に思えます。
私が考えることができる唯一の回避策はtype
、基本クラスにメンバーを追加しItem
、を使用する代わりにそれをチェックしdynamic_cast
、それが正しいタイプである場合はstatic_cast
代わりに使用することです。type
(割り当てられた値が競合しないように、どこかですべてのオブジェクトタイプについて知る必要があるという欠点があります。)
これが最善の解決策ですか、それとも別の方法がありますか?
明確化
議論のために、私が各オブジェクトタイプをファイルに書き込んでいると想像してください。 MovingItem
1つのファイルにTextItem
移動し、別のファイルにMovingTextItem
移動し、両方のファイルに移動します。したがって、どのインターフェイスが使用されているかを何らかの方法で判断して正しいファイルに書き込まれない限り、すべてのインターフェイスを実装する基本クラスを使用することはできません。