【发布时间】:2012-02-07 13:46:31
【问题描述】:
我有一个游戏对象的层次结构:
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
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?
【问题讨论】:
-
// then do stuff中有什么内容?根据这一点,您可以获得更好的解决方案。 (antiifcampaign.com) -
“有时我需要检测我正在处理的游戏对象的类型” - 这可能是您设计中的错误。如果您经常检查类型,那么尽管使用了类,但您并没有以面向对象的方式进行编程。要对不同类型做出不同的反应,请使用double dispatching。
-
非常相似的问题在这里:stackoverflow.com/questions/6123042/…
-
@TamásSzelei 相信我,使用枚举来检测实际对象类型是该项目中最漂亮的设计解决方案之一 :) 其他一切都要糟糕得多。顺便说一句,谢谢你的链接,我去看看