Are C++ polymorphic classes without any functions possible?

Viewed 1306

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.

4 Answers
Related