2016-02-16 82 views
4

我正在開發一個非常小而簡單的C++遊戲引擎。我有一個生物類和一個武器類。生物需要知道它有什麼武器,每個武器需要知道擁有它的生物。我希望武器知道生物具有何種功能的主要原因是爲了防止它破壞它自己的生物(當武器攻擊時,它將檢測它碰撞並殺死它們的所有生物,除了擁有武器的生物)。兩個需要相互引用的對象。餿主意?

這裏是(簡化)生物類的樣子:

class Creature { 
    private: 
    Weapon* weapon_; 
    public: 
    void SetWeapon(Weapon* w){ 
     // do some other stuff (e.g. remove Weapon from any other Creatures) 
     weapon_ = w; 
     w->creature_ = this; 
    } 
} 

這裏是(簡化)的武器類的樣子:

class Weapon{ 
    friend class Creature; // Creature needs access to creature_ pointer 
    private: 
    creature_; 
} 

正如你所看到的,我已經生物武器的朋友類,以便Creature的setWeapon()方法可以適當地設置私人生物_指針。

我的具體問題:

  1. 我聽說兩個對象引用對方是糟糕的設計。但就我而言,我怎麼會不這樣做呢?我真的「感覺到」每個生物都應該知道它有什麼武器,每個武器都應該知道生物具有什麼(以便它不會傷害生物)。有沒有什麼方法可以實現我想要的,而不需要讓這兩個類互相引用?我在Map/Entity,Inventory/Item等遊戲引擎中一次又一次地遇到了這個SAME問題。似乎每當我有一個「Container」類和一個「Item」類時,這個引用問題就會重新出現。我想把這個項目加入到其中一個類中,但我希望兩個類彼此知道(即我想讓生物知道它的武器和武器知道它的生物)。沒有任何方法可以實現這一點,而不需要兩個項目相互引用?

  2. 這種設計有時是必需的嗎?還是有一種通用的方式來總是避免它,但實現相同類型的功能?

  3. 如果這種設計對於實現這種功能來說確實是必要的,那麼使用朋友類是否有正確的方法來處理它?

非常感謝你提前。我非常有興趣學習如果有一種方法可以實現這種類型的功能,而不需要對象彼此引用。

+1

你有沒有考慮讓這個生物進攻而不是武器?然後,你可以擁有攻擊()方法,因爲該生物擁有武器並且該生物知道自己,所以該武器和生物都知道。 – Knox

+0

@Knox我的確在想這個,但是我希望攻擊行爲在於武器而不是生物。當一個生物被告知攻擊()時,它應該簡單地委託給weapon_.attack()。這將允許生物動態交換武器。 – MeLikeyCode

+0

然後或許讓生物的attack()方法調用武器的_attack(實體),這樣你可以爲武器範圍內的每個實體(不包括它本身)調用_attack()。 – Knox

回答

1

這樣那樣的問題時有發生的時間,並通過以下方法得到解決:

class Creature { 
public: 
    void SetWeapon(Weapon* w) { 
     weapon_ = w; 
     weapon_->SetCreature(this); 
    } 
private: 
    Weapon* weapon_; 
}; 

class Weapon { 
public: 
    void SetCreature(Creature* _creature) { 
     m_owner = _creature; 
    } 
private: 
    Creature* m_owner; 
}; 

關於您的廣泛的問題 - 如果你在同一個項目相當往往會碰到這樣那樣的問題,我建議您重新考慮您的設計解決方案。例如,你關於武器知道它的生物的主張是違反直覺的,並且感覺不正確。所以從這個假設開始,我相信你最終會得到更好的設計,在那裏你的武器不會知道他們的所有者(比如在現實生活中)。

+0

偉大的解決方案,但問題是,現在我無法改變武器屬於哪個生物。我可能應該提到,在我的問題中,我會繼續並更新它。謝謝! – MeLikeyCode

+0

@MeLikeyCode如果你將'Creature&_owner'改成'Creature * _owner',你會得到的# –

+0

@MeLikeyCode更新了我的答案 –

0
  1. 您沒有聽錯。以這種方式使用引用對象並不是一種好的編程習慣,但是再次使用goto也被一些人認爲是不好的方法。有關替代方案,請參閱下文

  2. 這個設計可以使用,因爲有時我們還需要使用goto循環。很多人不喜歡這種方式。

替代解決方案: 根據你需要我可以建議的替代方法是什麼希望這有助於。您可以創建struct以容納玩家對象和武器對象,而不是在其各自的課程中爲對方提供參考。這樣,根據需要操作和更改會更容易。即玩家可以擁有很多武器(在這種情況下,你可以在struct中創建一個陣列)。每個玩家都會有一個與它相關的武器實例。

+0

有趣的解決方案。不過我也有一個Map類。將Creatures添加到地圖非常直觀,但是將CreatureStruct添加到地圖對於我的遊戲引擎用戶來說會感覺很尷尬。儘管如此,我很高興你提出了這個問題,但我沒有立即想到這一點。謝謝! – MeLikeyCode

0

讓對象來回引用是很常見的。一個常見的例子是一個指向父代的指針。你的理念完全合理。只要確保你有你的析構函數,以便對象指針被清除。

~Weapon()中,清除Creature指向武器的指針,反之亦然。

+0

啊,謝謝你的回答。事實上,這是常見的和合理的,使我感覺好多了。謝謝! – MeLikeyCode