2011-11-29 59 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的指针已知的对象(比如通过智能指针),那么就会调用错误的析构函数。我在设计界面时遵循的原则之一是:使其难以以不安全的方式使用。这样可以节省您和其他人在路上的时间。 –

相关问题