2011-11-29 65 views
2

我在鏈表中​​存儲指向類Cell的所有實例的指針。 std::list<Cell*> cells存儲在名爲Game的類中。方法Game::update()迭代完成列表cells中保存的所有Cell實例,並調用每個單元的方法Cell::update()。如果Cell::update()方法在某個點發現該單元已準備好分割,則需要push_back()指向新單元的指針到cells,以便新單元可更新。 但是,如何才能在cell內參考Game::cells才能做到這一點?我曾考慮以下選項:C++:管理一組對象,以便持有的對象可以訪問持有它們的數據結構

  • 在全球範圍內定義std::list<Cell*> cells代替。
    • 令人作嘔,使得它不可能有一個以上的Game
  • 製作std::list<Cell*> cellsCell
    • 比全局變量更好的靜態成員,但仍避免使用多個Game實例
  • 將對當前遊戲的Game::cells的引用作爲參數傳遞給Cell的構造函數,並隨後存儲臨時副本在新建成的小區實例
    • 我認爲這是一個有點僵硬
  • 傳遞到當前遊戲的Game::cells的引用作爲參數傳遞給Cell::update()方法T參考

是否有更優雅解決方案利用?

+4

剛剛從'Cell :: update()'返回需要的東西,然後讓'Game'將新單元格推入列表中? – bbtrb

+0

我認爲,但如果細胞遭受奇怪的突變並決定分成4部分,我會返回什麼? – jms

+0

'std :: vector '將是一個簡單而直接的解決方案。在這一點上,我不會擔心很多性能問題,只是嘗試分工並正確設計界面。 – bbtrb

回答

4

我不會引入CellGame之間不必要的依賴性,如果所有Game確實是調用Cell的手法與持有它們的實例。

您可以改爲從Cell::update()返回新的Cell(或無),並讓Game決定要做什麼,最有可能將它們添加到列表中。您也可以在Cell中爲此定義一個新函數,如Cell::splitCell(),並且讓Cell::update()只更新Cell對象的屬性(如名稱所示)。

2

我可能會將Game的引用傳遞給Cell::update(),然後告訴Game對象分割單元格,但其他選項可能會更好,因爲我仍然不認爲我完全瞭解了您的總體目標是什麼。

+0

我不明白你的意思,爲什麼我要在Game :: update()中管理這個部門,而不是'Cell :: update()',如果我傳遞了一個對'Game'實例的引用? – jms

0

將參考Game傳遞給Cell構造函數。然後創建一個函數,讓Cell將其他Cell對象推到列表上(或使Cell爲朋友類Game,以便它可以直接訪問列表)。

這樣,Cell可以決定它何時需要分割,但它可以將操作委託給它所屬的對象Game

此外,如果有任何未來的事情Cell可能想Game這樣做,他已經擁有了正確的對象。

0

如果Cell對象必須知道它們屬於哪個Game對象,則從std :: list <>中派生一個類,並將一個指向Game(Game *)的指針作爲Cell的成員。然後Cell對象可以使用這個指針向遊戲添加另一個Cell。

class Game 
{ 
     class Cell 
     { 
      public: 
      Game *game; 
     }; 
     class Cells : public std::list<Cell *> 
     { 
      Game *game; 
      operator += (Cell *cell) {cell->game = this->game; ....} 
     }; 
     Cells cells; 
}; 
+0

從標準庫容器類派生並不是最好的想法。你必須非常小心(即保護或私人派生),你可以引入內存泄漏,因爲它們的析構函數不是虛擬的。 –

+0

如果將派生類嵌入到對象中,則會調用正確的析構函數。 –

+0

是的,如果您包含派生類已知的對象,則會調用正確的析構函數。如果你包含一個通過指向base的指針已知的對象(比如通過智能指針),那麼就會調用錯誤的析構函數。我在設計界面時遵循的原則之一是:使其難以以不安全的方式使用。這樣可以節省您和其他人在路上的時間。 –

相關問題