【发布时间】:2017-11-04 10:04:15
【问题描述】:
我正在制作一个基于文本的 RPG,其中我有一个抽象的 Item 类。从这个Item 类,我有Weapon、Potion、Key 和Armor 类。主要角色类Protagonist 使用这些项目并具有函数doItemEffect(Item*)。如何以一种我普遍引用所有项目的方式实现doItemEffect(Item*)?为了更好地表达我的问题,如果我不清楚,这里是一个使用非常丑陋的解决方案的示例。
class Protagonist
{
public:
void doItemEffect(Item* it)
{
switch(it->getType()) //<-- The type is an enum class
{
case ItemType::WEAPON:
attackOpponent(it.getAttackPower()); //If it is a weapon it would have this function
break;
case ItemType::POTION:
heal(it.getHealPower()); //If it is a weapon it would have this function
break;
case ItemType::KEY:
//..Code..
break;
case ItemType::ARMOR:
//More Code...
break;
}
};
以及Potion 和Weapon 中的两个类的示例(该类的类型是存储在Item 中的私有变量,带有一个突变方法setType()):
class Potion : public Item
{
int healPower;
public:
Potion(std::string name, std::string description) : Item(name, description)
{
setType(ItemType::POTION);
}
//Code
};
武器:
class Weapon : public Item
{
int attackPower;
public:
Weapon(std::string name, std::string description) : Item(name, description)
{
setType(ItemType::WEAPON);
}
//Code
};
如您所见,此代码依赖于Protagonist 类中的一个类代码和一个开关。因此,这似乎不是非常面向对象或多态的。因此,有没有一种方法可以让我得到一个 Item 类型的子类,而不必使用类代码?或者有没有其他解决方案?上面这个 sn-p 的另一个问题是,每当我引用其类之外的项目时,我必须对每种类型的项目使用相同的 switch 语句。
【问题讨论】:
-
给
Item一个虚函数,比如virtual void performEffectOn(Protagonist* p) = 0;。然后让每个项目相应地实施。例如。Weapon::performEffectOn(Protagonist* p) { p->attackOpponent(getAttackPower()); }最后,Protagonist::doItemEffect(Item* it)将简单地调用it->performEffectOn(this); -
这正是多态性解决的问题。
-
@IgorTandetnik 有没有办法在
Item不知道Protagonist的情况下做到这一点。我最初的解决方案实现了你所说的,但我想要一个能够解决我所指问题的解决方案。 -
我不确定我是否理解这个“你所指的问题”是什么。
Item知道Protagonist有什么问题?无论如何,您可能正在寻找Visitor pattern。
标签: c++ oop c++11 polymorphism