I have class Item
, one of no interest itself. However, I need some Item
s to be gear like clothes or weapons which need to additionally store an enum class Limb
object which represents the body part where they can be equipped. Moreover, ordinary Item
s must be placed together with "gear" Item
s in a single STL container and possibly be taken out later, maybe as a "gear" Item
. I see two options here: inheritance
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
or 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()
I like the first one for extensibility and compile-time type checking when a function expects Gear
(not just an Item
) instead of a runtime assert(item.is_gear())
inside it.
The second one seems better in terms of speed (I like to care about it even when there are no performance issues expected) and design naturalness: I don't need to know about any other class
es and special use cases when engineering Item
(for example, making its destructor virtual
like in the first variant would destroy this) which seems like clean and innocent design.
Which decision would be better and why? Or is there an even better solution?