2010-04-16 7 views
6

시뮬레이션에서 Boost MultiIndex 컨테이너를 사용하려고합니다. C++ 구문에 대한 지식이 매우 약하고 컨테이너에서 요소를 제대로 제거하지 못하거나 메모리에서 요소를 삭제하지 않는다고 우려합니다. 또한 요소를 수정해야하며 여기에서도 구문 및 기본 철학을 확인하기를 원했습니다.Boost MultiIndex Container의 요소 지우기 및 수정

// main.cpp 
... 
#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/hashed_index.hpp> 
#include <boost/multi_index/member.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/mem_fun.hpp> 
#include <boost/tokenizer.hpp> 
#include <boost/shared_ptr.hpp> 
... 
#include "Host.h" // class Host, all members private, using get fxns to access 

using boost::multi_index_container; 
using namespace boost::multi_index; 

typedef multi_index_container< 
    boost::shared_ptr<Host>, 
    indexed_by< 
    hashed_unique< const_mem_fun<Host,int,&Host::getID> > 
    // ordered_non_unique< BOOST_MULTI_INDEX_MEM_FUN(Host,int,&Host::getAge) > 
    > // end indexed_by 
    > HostContainer; 

typedef HostContainer::nth_index<0>::type HostsByID; 

int main() { 
    ... 
    HostContainer allHosts; 
    Host * newHostPtr; 
    newHostPtr = new Host(t, DOB, idCtr, 0, currentEvents); 
    allHosts.insert(boost::shared_ptr<Host>(newHostPtr)); 
    // allHosts gets filled up 

    int randomHostID = 4; 
    int newAge = 50; 
    modifyHost(randomHostID, allHosts, newAge); 
    killHost(randomHostID, allHosts); 
} 

void killHost(int id, HostContainer & hmap){ 
    HostsByID::iterator it = hmap.find(id); 
    cout << "Found host id " << (*it)->getID() << "Attempting to kill. hmap.size() before is " << hmap.size() << " and "; 
    hmap.erase(it); // Is this really erasing (freeing from mem) the underlying Host object? 
    cout << hmap.size() << " after." << endl; 
} 

void modifyHost(int id, HostContainer & hmap, int newAge){ 
    HostsByID::iterator it = hmap.find(id); 
    (*it) -> setAge(newAge); // Not actually the "modify" function for MultiIndex... 
} 

내 질문에 영구적으로 개체를 삭제하기에 충분하고 메모리에서 무료로 개체의 shared_ptr의에 반복자에 allHosts.erase(it)를 호출되면, MultiIndex 컨테이너에서 shared_ptrs의 allHostsHost에 객체

  1. 이다? 컨테이너에서 shared_ptr을 제거하는 것으로 보입니다.
  2. allhosts 컨테이너에는 현재 호스트의 ID에 의존하는 하나의 기능 색인이 있습니다. 시뮬레이션 과정에서 나이가 변하는 멤버 함수 (Host :: getAge())를 호출하는 정렬 된 두 번째 인덱스를 소개하면 인덱스를 참조 할 때 인덱스가 항상 업데이트됩니까?
  3. MultiIndex의 modify를 사용하여 기본 객체의 나이를 수정하는 것과 위에서 보여준 접근법의 차이점은 무엇입니까?
  4. MultiIndex에서 상수가 될 것으로 가정되는/모호한 것에 대해 나는 혼란스러워합니다.

미리 감사드립니다.


업데이트

는 여기에 내가 관련 부스트 example에 표시되는 내용에 따라 modify 구문 작업을 얻을 내 시도입니다.

struct update_age { 
    update_age():(){} // have no idea what this really does... elicits error 
    void operator() (boost::shared_ptr<Host> ptr) { 
    ptr->incrementAge(); // incrementAge() is a member function of class Host 
    } 
}; 

다음 modifyHost에, 나는 hmap.modify(it,update_age)이있을 것이다. 어떤 기적에 의해 이것이 옳았다는 것이 밝혀 지더라도, 나는 어떤 일이 벌어지고 있는지에 대한 어떤 종류의 설명을 좋아합니다.

답변

7

shared_ptr은 (shared_ptr의 다른 인스턴스가없는 경우) 소멸자에서 실제 Host 개체를 제거합니다. MultiIndex의 모든 객체는 상수로 간주됩니다. 객체를 수정하려면 modify의 MultiIndex 메서드를 사용해야합니다. 이 경우 필요에 따라 인덱스가 업데이트됩니다. 다음과 같이

struct change_age 
    { 
    change_age(int age) : age_(age) {}  
    void operator()(boost::shared_ptr<Host> h) // shared_ptr !!! 
    { 
     h->age = age_; 
    } 

    private: 
    int age_; 
    }; 

그 다음을 사용합니다 :

testHosts.modify(it, Host::change_age(22)); // set age to 22 
+0

다시 한번 감사

당신은 age 필드를 변경하려면 다음 펑터를 사용할 수 있습니다. 링크를 연구 한 후에도 수정 구문에 여전히 문제가 있습니다. Host :: incrementAge()를 사용하여 hmap.modify (it, incrementAge())를 사용하면 범위를 벗어난 오류가 발생합니다. (컨테이너 요소가 개체 자체 일 때) structs를 사용하는 몇 가지 예제를 볼 수 있지만 내 코드가 작동하지 않는 이유를 따라갈 수 없습니다. – Sarah

+0

'modify '를 사용하는 방법을 보여주기 위해 제 대답이 업데이트되었습니다. –

+0

감사합니다. Kirill - 매우 유용합니다. (필자는 입력을받는 다른 멤버 함수가 있고 modify()로 호출해야합니다.) 입력을받지 않는 멤버 함수를 호출하려고 할 때 수행 할 작업에 대해 여전히 혼란 스럽습니다. 그래도 위 편집 코드가 맞습니까? – Sarah

관련 문제