2014-01-13 45 views
3

我有一個關於如何在C++中解決以下問題:項目系統問題繼承

因此,說我有2個項目。一把劍和一把刀。

阿劍的結構如下所示:

baseItem > Equippable (Holds events and boolean checks) > Weapon (Same) > Sword 

刀的結構如下所示:

baseItem > Equippable > Weapon > Knife 

我大部分的類和函數將要處理的項目(庫存,集裝箱,創建Item實例的函數)都將是baseItem類型的。

如何指定功能,如:

baseItem createItem(int index, type itemType) 
以這樣的方式,我可以退貨或投備份到劍/刀

?這對於庫存尤爲重要,因爲我需要從ItemSlot中拉出物品,這些物品也會持有baseItem類型的物品,但需要不斷檢查它們是劍,刀等。

回答

3

你可以用一個模板成員函數做到這一點,就像這樣:

class baseItem { 
    ... // Private members 
public: 
    template <typename T> static T* createItem(int index); 
}; 

然後,你將能夠在一個類型參數與精確的類型來調用這個,像這樣:

Sword *sword = basrItem::createItem<Sword>(123); 

Demo on ideone.

有兩點要注意:

  • 您需要通過指針,普通或「智能」來返回,以避免object slicing
  • 你可能想如果你保持一個註冊表,以createItem構件移動到一個單獨的「工廠」 /「註冊表」類
  • ,你需要小心你的對象的所有權(即避免刪除它們時,它們是在註冊表內部,或者當他們在其他地方使用時,它們就會退出註冊表)。

爲了說明這最後一點,這裏是我的意思是由註冊表類:

class baseItemRegistry { 
    map<int,unique_ptr<baseItem> > registry; 
public: 
    template <typename T> static T* createItem(int index) { 
     map<int,baseItem*>::const_iterator iter = registry.find(index); 
     if (iter != registry.end()) { 
      return dynamic_cast<T*>(iter->second); 
     } 
     T* res = new T(index); 
     registry[index] = res; 
     return res; 
    } 
}; 

這將讓你保持baseItemRegistry對象,你可以決定要分享,但你也可以將其隱藏它需要一個「私人」註冊表。 static函數不會給你這種靈活性。

+0

多次通話都會返回劍嗎?如果是這樣,這對我不起作用。 – Sinistralis

+0

@Sinistralis多次調用會返回您要求他們返回的任何內容。如果您調用'Knife * knife = basrItem :: createItem (321)',則會返回一個Knife對象。 – dasblinkenlight

+0

好的,這聽起來完全像我需要的那樣。我的最後一個問題是,存儲被指向的對象的最佳方式是什麼?你用筆記觸及了它的基礎,但我不確定是否完全遵循。現在我將這些項目存儲在Vector中,並且工作正常。我實際上正在製作「實例」項目,這些項目包含每個項目的數據,這些都是需要存儲位置的內容。 – Sinistralis

0

例如,您可能會返回一個指針(最好包裹在某種智能指針中),例如, shared_ptr

std::shared_ptr<baseItem> createItem(int index, type itemType) 
{ 
    // Your logic 
    return std::shared_ptr<baseItem>(new Sword()); // or whatever 
} // eo createItem 

,然後再使用dynamic_cast你投以適當的類型上。

0

通常情況下,您可以使用dynamic_cast投射baseItem刀或劍,但這不是一個好習慣。基本上,所有依賴於對象類型的行爲都應該位於類的虛擬成員函數中。

+0

我從刀 - > baseItem去了這個覆蓋。當我有非靜態數據擔心時,你應該如何做到這一點? (如耐久性) – Sinistralis