c++ - Common interface for all derived classes -
i have base class item store data , grant access accessors, like:
class item{ (...) public: int get_value(); double get_weight(); itemmaterial get_material(); (...) }
then i've got derived classes weapon, armor add additional data:
class weapon : public item { (...) public: int get_dmg(); (...) }
i store these items in container:
std::vector<item*> inventory;
and here comes problem interface - how access derived class data? thinking, , got 3 ideas:
1. separate interfaces
each derived class adds data, shown above, , use dynamic_cast:
item *item = new weapon; int dmg = dynamic_cast<weapon*>(item)->get_dmg();
2. common interface class
make interface class accessors:
iteminterface{ public: virtual int get_value() = 0; //item interface virtual double get_weight() = 0; (..) virtual int get_dmg() = 0; //weapon interface (...) }
and this:
item : public iteminterface{ (...) }
and
weapon : public item { (...) }
and can access data:
item *item = new weapon; int dmg = item->get_dmg();
3. combination templates , enums
this idea maybe little weird :-) but:
implement enum item data:
enum class itemdata{ value, weight, material, //item data (...) damage, //weapon data (...) defense, //armor data etc. (...) null }
and in base class template function this:
template<typename t> t get_data(itemdata data){ switch(data){ case itemdata::value: return _value; break; case itemdata::damage: return _dmg; break; (...) } }
and access data like:
item *item = new weapon; ind dmg = item->get_data<int>(itemdata::damage);
===
how think should done? grateful advices!
regards.
your second , third option not way go - whenever add new type of item, have change base class or enum - not want if need basic form of maintainability in code.
and here comes problem interface - how access derived class data
first have think of "where code this"? of code dealing whole inventory
should use content item*
, using functions item
class.
if have code specificially dealing weapon
objects, place weapon
objects created (and inserted inventory
), may add them variable, maybe weapons list in form of
std::vector<weapon*> weapons;
or member variable weapon*
of class warrior
or (but beware, have 2 pointers same objects, have think ownership). code dealing weapons (for example, member function of warrior
) not access inventory
weapon
object, use weapon*
directly.
if, reasons, have write code weapons inventory, write single function extracts weapon
objects using dynamic_cast
(or better: make iterator function), , reuse function whenever need access weapons. don't clutter code on dynamic casts, keep in 1 place.
edit: alternative (avoiding dynmic cast) using visitor pattern, see this post. don't answer of post, in presented form imply cyclic dependency "base -> visitor -> derived -> base", imho bad design.
Comments
Post a Comment