【发布时间】:2014-06-08 09:05:04
【问题描述】:
我有基类 Item ,它存储一些数据并授予访问者对其的访问权限,例如:
class Item{
(...)
public:
int get_value();
double get_weight();
ItemMaterial get_material();
(...)
}
然后我得到了像 Weapon、Armor 这样的派生类,它们添加了一些额外的数据:
class Weapon : public Item {
(...)
public:
int get_dmg();
(...)
}
我将这些项目存储在某个容器中:
std::vector<Item*> inventory;
接口的问题来了——如何访问派生类数据?我在想,得到了 3 个想法:
1.单独的接口
每个派生类添加其数据,如上图所示,然后使用dynamic_cast:
Item *item = new Weapon;
int dmg = dynamic_cast<Weapon*>(item)->get_dmg();
2。通用接口类
创建一个包含所有访问器的接口类:
ItemInterface{
public:
virtual int get_value() = 0; //Item interface
virtual double get_weight() = 0;
(..)
virtual int get_dmg() = 0; //Weapon interface
(...)
}
然后是这样的:
Item : public ItemInterface{ (...) }
和
Weapon : public Item { (...) }
最后我们可以访问数据了:
Item *item = new Weapon;
int dmg = item->get_dmg();
3.结合模板和枚举
这个想法可能有点奇怪 :-) 但是:
使用所有项目数据实现枚举:
enum class ItemData{
Value,
Weight,
Material, //Item data
(...)
Damage, //Weapon data
(...)
Defense, //armor data etc.
(...)
Null
}
在基类中一些模板函数是这样的:
template<typename T>
T get_data(ItemData data){
switch(data){
case ItemData::Value: return _value; break;
case ItemData::Damage: return _dmg; break;
(...)
}
}
并访问以下数据:
Item *item = new Weapon;
ind dmg = item->get_data<int>(ItemData::Damage);
===
你觉得应该怎么做?如有任何建议,我将不胜感激!
问候。
【问题讨论】:
-
如果您需要访问特定的派生类内容,为什么要使用指向基的指针?换句话说,给定一个任意的
Item*,你怎么知道它适合转换为Weapon*以获得武器专用的东西? -
没有一个好 - 如果你不能为你的数据建模,使用 dynamic_cast
-
因为,例如,对象 Creature 包含库存,如示例所示,并且我想在此容器中保存所有基于 Item 的类。如果合适? dynamic_cast 给了我这个信息。在其他情况下,我认为我应该,例如,在提供此信息的基类中添加一些数据字段..
-
@Dieter Lücking:那么第一个解决方案?
-
查看访问者模式以获得另一种选择。
标签: c++