2010-04-16 8 views
6

Sto tentando di utilizzare un contenitore Boost MultiIndex nella mia simulazione. La mia conoscenza della sintassi C++ è molto debole, e sono preoccupato di non rimuovere correttamente un elemento dal contenitore o di cancellarlo dalla memoria. Ho anche bisogno di modificare elementi, e speravo di confermare anche qui la sintassi e la filosofia di base.Cancellazione e modifica di elementi nel contenitore MultiIndex Boost

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

Le mie domande sono

  1. Nel contenitore MultiIndex allHosts di shared_ptrs a Host oggetti, sta chiamando allHosts.erase(it) su un iteratore per shared_ptr dell'oggetto sufficiente per eliminare l'oggetto in modo permanente e libera dalla memoria? Sembra che stia rimuovendo shared_ptr dal contenitore.
  2. Il contenitore allhosts ha attualmente un indice funzionante che si basa sull'ID dell'host. Se introduco un secondo indice ordinato che chiama una funzione membro (Host :: getAge()), dove l'età cambia nel corso della simulazione, l'indice verrà sempre aggiornato quando farò riferimento ad esso?
  3. Qual è la differenza tra l'uso della modifica di MultiIndex per modificare l'età dell'oggetto sottostante rispetto all'approccio mostrato sopra?
  4. Sono vagamente confuso su ciò che viene assunto/richiesto per essere costante in MultiIndex.

Grazie in anticipo.


Aggiornamento

Ecco il mio tentativo di ottenere il lavoro modify sintassi, in base a quello che vedo in un Boost correlato example.

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

e poi in modifyHost, avrei hmap.modify(it,update_age). Anche se per qualche miracolo questo risulta essere giusto, mi piacerebbe una specie di spiegazione di quello che sta succedendo.

risposta

7

shared_ptr rimuoverà l'oggetto effettivo Host nel suo distruttore (se non ci sono altre istanze di shared_ptr). Tutti gli oggetti in MultiIndex sono considerati costanti. Per modificare l'oggetto, utilizzare il metodo modify di MultiIndex. In tal caso gli indici saranno aggiornati se necessario.

è possibile utilizzare il seguente funtore di cambiare age campo:

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

    private: 
    int age_; 
    }; 

quindi utilizzarlo come segue:

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

Grazie ancora. Anche dopo aver studiato il tuo link, sto ancora avendo problemi con la sintassi di modifica. L'utilizzo di hmap.modify (it, incrementAge()), con Host :: incrementAge(), provoca un errore di ambito. Vedo alcuni esempi con le strutture (quando gli elementi del contenitore sono gli oggetti stessi) ma non riesco a capire perché il mio codice non funzioni. – Sarah

+0

Aggiornato la mia risposta per mostrare come usare 'modify'. –

+0

Grazie, Kirill - è molto utile. (Ho altre funzioni membro che prendono input e che dovrò invocare con modify().) Sono ancora confuso su cosa fare quando sto solo provando a chiamare una funzione membro che non prende input, però - il mio codice è stato modificato in alto a destra? – Sarah

Problemi correlati