我有一个游戏对象层次结构:

class GameObject {
public:
    virtual void update(float dt) = 0;
    virtual void draw() = 0;
};
class Building : public GameObject {}
class Sawmill : public Building {}
class Human : public GameObject {}

等等。所有对象都由游戏管理(这不是GameObject的子类:)。游戏将所有对象存储在std::vector 中,并成功调用了诸如update和draw之类的虚拟方法,这一切都很好。但是有时候我需要检测我正在处理哪种类型的GameObject。对于这种情况,我们提出了一个解决方案:GameObject具有一个GameObject类型的枚举,并且每个GameObject子类都从该枚举中返回自己的值。
class GameObject {
public:
    enum GOType
    {
        GOGameObject,
        GOBuilding,
        GOSawmill,
        GOHuman,
        ...
    }
    static GOType Type() { return GOGameObject; }
    virtual GOType getType() const { return GameObject::Type(); }
};

class Building : public GameObject {
public:
    static GOType Type() { return GOBuilding; }
    virtual GOType getType() const { return Building::Type(); }
};

因此,GameObject的每个子类都有其自己的“静态GOType Type()”方法版本,该方法从枚举GOType返回一个值。并且它已经重载了虚方法“GOType getType()const”,该虚方法只是调用了它自己的类方法Type()。在游戏中的任何地方,我都可以检查我所指向的对象是否为建筑物:
if (obj && obj->getType() == Building::Type()) {
    // then do stuff
}

明确地说-这个解决方案很好用,并且已经证明自己是可扩展的并且非常有效(我们想到的第一个解决方案是在getType()中返回字符串并进行比较;速度很慢)。

我看到的唯一缺点是,每次添加新的GameObject子类时,都必须在GameObject中扩展GOType。现在它包含大约一百种类型,并且看起来和感觉都不漂亮(我在这里是一个完美主义者:)

所以,我的问题是:是否有其他解决方案能像此解决方案一样有效,但无需在GameObject中扩展GOType?

最佳答案

与其拥有大量的继承类链,不为什么不对drawupdate函数进行模板化,以便您可以传递任何T,它将执行您需要的任何操作。如果您需要针对特定​​的T具有不同的行为,则可以进行专门研究。

只是一个建议。

关于c++ - 层次结构中的对象类型检测,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9177352/

10-11 22:39
查看更多