Я пытаюсь создать некоторые классы, которые содержат только элементы данных (без функций ), но я хотел бы, чтобы они были полиморфными -, под которыми я подразумеваю, что буду передавать объекты с помощью указателя на базовый класс, и мне нужна возможность dynamic_cast
преобразовать их в определенный производный тип (и получить результирующее значение NULL
, если экземпляр не относится к данному типу.)
Например, у меня есть элемент:
struct Item {
int x, y;
}
У меня также есть элемент, который движется, и другой, содержащий текст:
struct MovingItem: virtual public Item {
int speedX, speedY;
}
struct TextItem: virtual public Item {
std::string text;
}
Предположительно, я должен использовать виртуальное наследование выше, потому что я также хочу элемент, который движется и имеет текст, но мне нужен только один набор координат с верхнего -уровня 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
относится к одному файлу, TextItem
— к другому файлу, а MovingTextItem
— к обоим файлам. Таким образом, базовый класс, который реализует каждый интерфейс , не будет работать,если я не могу каким-то образом определить, какие интерфейсы используются, чтобы они записывались в правильные файлы.