0

假设我有一个对象列表 objA。现在 objA 可以创建更多的 objA,它们之间将完全无关——它们根本不关心知道其他 objA 的存在。我怎么能得到另一个 objA 创建的 objA 而不将 objA 存储在它的生成器中?我不想使用单例来表示 objA 的列表。

例子:

class Container
{  
     list<Monster*> listOfMonsters;

     void UpdateAllMonsters()
     {
          foreach(Monster monster in listOfMonsters)
          {
              monster.Update();
          }
     }         

};

class Monster
{
    void Update()
    { 
         new Monster();
    }
};

如何获取在 Update() 方法中创建的 Monster 并将其粘贴到 Containers listOfMonsters 中?我只想要一个 Container 对象的实例漂浮在周围,而怪物不应该对容器对象做任何事情。

我想到的一种解决方案是在 Container 和 Monster 之间创建一个中间对象,这样就只有 Container 对象的一个​​实例,并且 Monster 基本上只能访问 Container 对象的一种方法(这将添加到怪物列表)。

IE;

class Container
{  
     list<Monster*> listOfMonsters;

     void UpdateAllMonsters()
     {
          foreach(Monster monster in listOfMonsters)
          {
              monster.Update();
          }
     }         

     void AddToList(Monster* monster)
     {
         listOfMonsters.add(monster);
     }


};


class ContainerLiason
{
     private __Container*;

     AddToContainer(Monster* monster)
     {
         __Container.AddToList(monster);
     }
};

class Monster
{

    private ContainerLiason* __liason;
    void Update()
    { 
         __liason.AddToContainer(new Monster());
    }
};

还有其他想法或设计模式吗?还有一件事,上面的例子会是一种设计模式吗?如果是,它会被称为什么?我只是问,因为我在知道它们被称为什么甚至它们是什么之前就使用过单例。

4

3 回答 3

2

工厂模式应该做你需要的。让容器(又名工厂)不仅保存已创建对象的列表,还要处理对象创建本身:

class Factory {  
  list<shared_ptr<Monster>> listOfMonsters;
public:
  void UpdateAllMonsters() {
    for(auto pMonster : listOfMonsters)  {
      monster->Update();
    }
  }         

  shared_ptr<Monster> createMonster() {
    auto newMonster = make_shared<Monster>();
    listOfMonsters.push_back(newMonster);
    return newMonster;
  }
};

class Monster {
  shared_ptr<Factory> theFactory;
public:
  void Update() { 
    auto newMonster = theFactory->createMonster();
    // ...
  }
};

另请注意,您在 C++ 标签下询问 - 您的代码看起来并不像它

于 2013-06-12T09:51:38.847 回答
1

您的解决方案似乎是一个,您只需要确保所有怪物在 ContainerLiaison 上都有相同的指针,如果需要,可以使用参考。

另一种解决方案是在每个怪物的 Container 上都有一个参考,但我认为你的 ContainerLiason 更好。

最后一个解决方案是静态元素和函数,但我不喜欢它。

我建议你保留你的解决方案

于 2013-06-12T09:51:20.860 回答
0

好的,所以你绝对不需要在这里使用单例。最简单的选择就是简单地Update将 MonsterContainer 的引用作为参数。

class Container
{  
     using MonsterList = list<Monster*>; // you should use a shared container or shared_ptrs here instead I think.
     MonsterList listOfMonsters;

     void UpdateAllMonsters()
     {
          foreach(Monster monster in listOfMonsters)
          {
              monster.Update(listOfMonsters);
          }
     }         

};

class Monster
{
    // You should change the name of your function here. Update does not imply
    // creation to me. I would call it "CreateMonsterInList"
    void Update(MonsterList& monsterContainer)
    { 
         monsterContainer.add( new Monster() );
    }
}
于 2013-06-12T09:51:29.440 回答