У меня есть class Item
, сам по себе не интересен. Тем не менее, мне нужно несколько Item
s для снаряжения, подобного одежде или оружию, которые должны дополнительно хранить объект enum class Limb
, представляющий часть тела, где они могут быть экипированы. Более того, обычные Item
s должны быть помещены вместе с «gear» Item
s в один контейнер STL и, возможно, вынуты позже, возможно, как «gear» Item
. Я вижу здесь два варианта: наследование
class Item { /* ... */ };
class Gear : public Item {
Limb limb;
// ...
};
std::vector<std::unique_ptr<Item>> items;
std::unique_ptr<Gear> gear = // dynamic cast items[...] and check for success
или std::optional
class Item {
std::optional<Limb> limb; // if equippable, limb.has_value() == true
// ...
};
std::vector<Item> items;
Item gear = // get items[...] and check limb.has_value()
Мне нравится первый вариант для расширяемости и проверки типов во время компиляции, когда функция ожидает Gear
( не просто Item
) вместо времени выполнения assert(item.is_gear())
внутри него.
Второй кажется лучше с точки зрения скорости (мне нравится заботиться об этом, даже когда проблем с производительностью не ожидается) и дизайном естественность: мне не нужно знать о каких-либо других class
es и особых случаях использования, когда инженерия Item
(например, создание ее деструктора virtual
, как в первом варианте разрушило бы это), которая кажется чистой и невинной дизайн.
Какое решение будет лучше и почему? Или есть еще лучшее решение?