Стирание и изменение элементов в Boost MultiIndex Container - PullRequest
7 голосов
/ 16 апреля 2010

Я пытаюсь использовать контейнер Boost MultiIndex в моей симуляции.Мои знания синтаксиса C ++ очень слабые, и я обеспокоен тем, что неправильно удаляю элемент из контейнера или удаляю его из памяти.Мне также нужно изменить элементы, и я надеялся также подтвердить синтаксис и базовую философию здесь.

// 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...
}

Мои вопросы

  1. В контейнере MultiIndex allHosts изshared_ptrs для Host объектов, вызывает ли allHosts.erase( it ) на итераторе для объекта shared_ptr достаточно, чтобы удалить объект навсегда и освободить его из памяти?Кажется, что он удаляет shared_ptr из контейнера.
  2. Контейнер allhosts в настоящее время имеет один работающий индекс, который зависит от идентификатора хоста.Если я ввожу упорядоченный второй индекс, который вызывает функцию-член (Host :: getAge ()), где возраст изменяется в течение моделирования, всегда ли будет обновляться индекс, когда я на него ссылаюсь?
  3. В чем разница между использованием модификации MultiIndex для изменения возраста базового объекта по сравнению с подходом, который я показываю выше?
  4. Я смутно запутался в том, что предполагается / требуется быть постоянным в MultiIndex.

Заранее спасибо.


Обновление

Вот моя попытка заставить работать синтаксис modify, основываясь на том, чтоЯ вижу в связанном Boost примере .

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).Даже если каким-то чудом это окажется правильным, я бы с удовольствием объяснил, что происходит.

1 Ответ

8 голосов
/ 16 апреля 2010

shared_ptr удалит фактический Host объект в его деструкторе (если других экземпляров shared_ptr нет).Все объекты в MultiIndex считаются постоянными.Для изменения объекта вы должны использовать метод modify из MultiIndex.В этом случае индексы будут обновляться при необходимости.

Вы можете использовать следующий функтор для изменения поля age:

  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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...