2013-06-12 4 views
0

Предположим, у меня есть список объектов, objA. Теперь objA может создать больше objA, и они будут полностью не связаны друг с другом - они не хотят знать о существовании других objA в малейшей степени. Как я могу получить objA, созданный другим objA, без сохранения objA внутри его создателя? Я не хочу использовать singleton для представления списка objA.Отслеживание объектов, созданных другими объектами?

Пример:

class Container 
{ 
    list<Monster*> listOfMonsters; 

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

}; 

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

Как я мог получить монстра, созданного в() метод Update и вставить его в контейнеры listOfMonsters? Мне нужен только один экземпляр объекта Container, плавающий вокруг, и монстры не должны ничего делать с объектом-контейнером.

Одно из решений, о котором я думал, - это создание промежуточного объекта между контейнером и монстром, так что будет только один экземпляр объекта Container, и монстр может по существу только получить доступ к одному из методов объекта Container (который будет добавлять в listOfMonsters).

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()); 
    } 
}; 

Есть ли какие-либо другие идеи или образцы дизайна? Еще одна вещь: был ли приведенный выше пример типом шаблона дизайна и что бы он назвал, если так? Я просто спрашиваю, потому что я использовал синглеты, прежде чем знал, что они называли или даже тем, кем они были.

ответ

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(); 
    // ... 
    } 
}; 

Заметим также, что вы просили под С ++ тег - код не действительно выглядеть это

+0

Я знаю, что мой код на самом деле не похож на C++ - хотя я использовал тег C++ - я больше пытался писать psuedo-код (думаю, он оказался более похожим на C#, чем что-либо) GDI Enter ключ. Не могли бы вы объяснить пару вещей? Я никогда не использовал shared_ptr (или любой умный указатель). Я не полностью понимаю, почему я бы использовал shared_ptr - не могли бы вы объяснить, пожалуйста? –

+0

Ну, я думаю, что одного комментария SO недостаточно, чтобы рассказать вам о полезности умных указателей, но в Интернете есть обширные ресурсы, которые могут познакомить вас с этой темой. Они считаются частью «современного C++», и не использовать их (где они подходят) все чаще считаются плохим дизайном.'auto' не является избыточным в моем коде, это * не * полностью избыточный спецификатор хранилища от C++ 98, но ключевое слово для вычитания автоматического типа из C++ 11. Тебе тоже захочется посмотреть. –

+0

+1 - Это чистое решение. – Dennis

1

Ваше решение похоже на то, что вам нужно только убедиться, что все монстры имеют один и тот же указатель на ContainerLiaison, вы можете использовать ссылку, если хотите.

Другое решение - иметь ссылку на Контейнер в каждом монстре, но я думаю, что ваш ContainerLiason лучше.

Последнее решение - это статический элемент и функция, но мне это не нравится.

Я предлагаю вам сохранить ваше решение

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()); 
    } 
} 
Смежные вопросы