我已經得到了遊戲對象的層次結構:對象類型檢測層次
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 < GameObject * >中,併成功調用了更新和繪製等虛擬方法,這一切都很好。但有時我需要檢測我正在處理的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(); }
};
所以,遊戲對象的每個子類都有它返回從枚舉GOType值「靜態GOType類型()」方法的自己的版本。它重載了虛擬方法「GOType getType()const」,它只是調用它自己的類方法Type()。任何地方比賽,我可以檢查對象我有一個指向是,例如,一個大廈:
if (obj && obj->getType() == Building::Type()) {
// then do stuff
}
要清楚 - 這個解決方案工作正常,並已證明是可擴展的,非常有效的(在我們提出的第一個解決方案是在getType()中返回字符串並對它們進行比較;它們的速度很慢)。
唯一的缺點我看到的是,我必須在遊戲對象每次添加一個新的遊戲對象的子類時間延長GOType。現在它包含大約一百種類型,它看起來並不美觀(我在這裏是一個完美主義者:)
所以,我的問題是:是否有任何其他解決方案的問題是有效的這一個,但沒有必要在GameObject中擴展GOType?
您可以使用typeid的 – 2012-02-07 13:52:40
什麼去'//然後做stuff'?根據這一點,你可以得到更好的解決方案。 (http://www.antiifcampaign.com/) – 2012-02-07 13:55:38
「有時我需要檢測我正在處理的遊戲對象的類型」 - 這可能是您設計中的錯誤。如果你經常檢查類型,那麼儘管使用類,你仍然不是以面向對象的方式進行編程。對於不同類型的反應,請使用[double dispatch](http://en.wikipedia.org/wiki/Double_dispatch)。 – 2012-02-07 13:57:18