2013-06-12 3 views
0

개체의 목록 인 objA가 있다고 가정 해 보겠습니다. 이제 objA는 더 많은 objA를 생성 할 수 있으며 서로 전혀 관련이 없습니다. 다른 objA 존재에 대해 알지 못합니다. objA를 spawner 안에 저장하지 않고 다른 objA에서 만든 objA를 어떻게 얻을 수 있습니까? objA 목록을 나타내는 데 싱글 톤을 사용하고 싶지 않습니다.다른 개체에서 생성 된 개체를 추적하고 있습니까?

예 :

class Container 
{ 
    list<Monster*> listOfMonsters; 

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

}; 

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

어떻게 업데이트() 메소드에서 만든 몬스터를 얻고 컨테이너 listOfMonsters에 대항 할 수 있을까? 컨테이너 객체의 한 인스턴스 만 주위에 떠 다니고 싶을 뿐이며, 괴물은 컨테이너 객체로 아무 것도 할 수 없어야합니다.

내가 생각한 한 가지 해결책은 컨테이너와 몬스터 사이에 중간 개체를 만들어서 컨테이너 개체의 인스턴스가 하나 뿐이므로 괴물은 본질적으로 컨테이너 개체의 한 메서드에만 액세스 할 수 있습니다. 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

공장 패턴은 필요한 것을 수행해야합니다. 코드가 정말처럼 보이지 않는 - 당신은 C++ 태그 아래에 묻는 것이

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

음, 한 가지 의견으로는 스마트 포인터의 유용성에 대해 이야기하는 것만으로는 충분하지 않다고 생각하지만 웹에서 주제를 소개 할 수있는 광범위한 자료가 있습니다. 그것들은 "현대 C++"의 일부로 간주되며, (적절한 경우) 점점 더 나쁜 디자인으로 간주됩니다.'auto'는 내 코드에서 중복되지 않습니다. C++ 98의 완전히 중복 된 저장 지정자가 아니라 C++ 11의 자동 유형 공제 키워드입니다. 너도 그걸 보길 원할거야. –

+0

+1 - 이것은 깨끗한 해결책입니다. – Dennis

1

당신의 솔루션이 하나 인 것처럼 보입니다. 모든 괴물이 ContainerLiaison에서 동일한 포인터를 가지고 있는지 확인하기 만하면됩니다. 원하는 경우 참조를 사용할 수 있습니다.

다른 해결책은 각 몬스터의 컨테이너에 대한 참조를하는 것이지만, 귀하의 ContainerLiason이 더 좋다고 생각합니다.

마지막 해결책은 정적 요소 및 기능이지만, 나는 그것을 좋아하지 않습니다.

나는 당신은 분명히 여기에 싱글 톤을 사용할 필요가 없습니다 있도록,

0

좋아 솔루션을 유지하는 것이 좋습니다. 가장 단순한 옵션은 MonsterContainer에 대한 참조를 매개 변수로 사용하여 간단하게 Update입니다.

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()); 
    } 
} 
관련 문제