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