I am trying to create some classes which only contain data members (no functions) but I would like them to be polymorphic - by which I mean I will be passing around the objects by a pointer to the base class, and I need the ability to dynamic_cast
them to a specific derived type (and have the resulting value be NULL
if the instance is not of the given type.)
By way of example, I have an item:
struct Item {
int x, y;
}
I also have an item which moves, and another which contains text:
struct MovingItem: virtual public Item {
int speedX, speedY;
}
struct TextItem: virtual public Item {
std::string text;
}
Presumably I have to use virtual inheritance above, because I also want an item that moves and has text, but I only want the one set of coordinates from the top-level Item
:
struct MovingTextItem: virtual public MovingItem, virtual public TextItem {
}
These can all be defined correctly, but when I try to dynamic_cast
an Item *
to see what type it is, my compiler complains that the source types aren't polymorphic.
void example(Item *i) {
MovingTextItem *mti = dynamic_cast<MovingTextItem *>(i); // error!
}
This would work if I reimplemented the whole thing using virtual functions instead of data members, but this seems like a waste as I never need to override anything.
The only workaround I can think of is to add a type
member to the base Item
class, and check that instead of using dynamic_cast
, and if it's of the correct type then use static_cast
instead. (The drawback there being I have to know about all object types somewhere so the assigned type
values don't conflict.)
Is this the best solution, or is there another way?
Clarification
For arguments' sake, imagine I am writing each object type to a file. MovingItem
goes to one file, TextItem
goes to a different file, and MovingTextItem
goes to both files. So having a base class which implements every interface won't work, unless I can somehow tell which interfaces are in use so they get written to the correct files.