获取派生类属性的最佳设计是什么?

问题描述 投票:0回答:1
class Item
{
// public:
//    virtual int GetDamage() const { return -1; }
};

class Weapon : public Item
{
public:
    Weapon(int InDamage)
        :Damage(InDamage)
    {
    }

    int GetDamage() const { return Damage; }
    // virtual int GetDamage() const override { return Damage; }

private:
    int Damage = 0;
};

class Armor : public Item
{
public:
    Armor(int InDefence)
        :Defence(InDefence)
    {
    }

    int GetDefence() const { return Defence; }

private:
    int Defence = 0;
};

class ItemManager
{
public:
    ItemManager()
    {
        ItemMap.insert
        ({
            {"Weapon", new Weapon(50)},
            {"Armor", new Armor(100)},
        });
    }

    Item* GetItem(const std::string& ItemName) const
    {
        const auto It = ItemMap.find(ItemName);
        return It->second;
    }

private:
    std::map<std::string, Item*> ItemMap;
};


int main()
{
    ItemManager Manager;

    Item* ItemInst = Manager.GetItem("Weapon");
//  const int Damage = ItemInst->GetDamage()

//  Weapon* WeaponInst = dynamic_cast<Weapon*>(ItemInst);
//  std::cout << WeaponInst->GetDamage() << std::endl;

    return 0;
}

这是代码示例。

我所拥有的从物品中获得武器伤害的解决方案是

  1. 使用dynamic_cast将物品投射到武器上。
  2. 在 Item 类中添加 GetDamage 虚函数,并覆盖它,即使盔甲不需要。

我对这些解决方案感到非常不舒服。

这就像我试图破坏“SOLID设计原则”。

我确信,有更好的解决方案,只是我不知道。

请教我最好的代码设计。

提前致谢。

c++ design-patterns solid-principles
1个回答
0
投票

使用dynamic_cast将物品投射到武器上。

没有

在 Item 类中添加 GetDamage 虚函数,并覆盖它,即使盔甲不需要。

也没有。如果您的所有项目都可以共享一个像

item->getName();
这样的通用接口,那么这个解决方案会很好。然而,在你的情况下,
damage
显然只与武器相关,而
defence
与盔甲相关。您的设计很快就会因您被迫覆盖的不相关方法而爆炸。

您的一个解决方案是使用通用接口来获取您的项目属性:

class Item {
public:
    virtual ~Item()                       = default;
    virtual int getProperty(std::string propName) = 0;
};

class Weapon : public Item {
public:
    Weapon(int dam) { _props["damage"] = dam; }
    int getProperty(std::string propName) override {
        if (!_props.count(propName)) {
            throw std::runtime_error("Property not found");
        }
        return _props[propName];
    }

private:
    std::unordered_map<std::string, int> _props;
};

你还可以有一个接口来获取所有这些,检查 prop 是否存在(无一例外),等等

© www.soinside.com 2019 - 2024. All rights reserved.