2010-04-16 15 views
6

Estoy tratando de usar un contenedor Boost MultiIndex en mi simulación. Mi conocimiento de la sintaxis de C++ es muy débil, y me preocupa que no elimine correctamente un elemento del contenedor o lo elimine de la memoria. También necesito modificar elementos, y esperaba confirmar la sintaxis y la filosofía básica aquí también.Borrado y modificación de elementos en 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... 
} 

Mis preguntas son

  1. En el contenedor MultiIndex allHosts de shared_ptrs a Host objetos, está llamando allHosts.erase(it) en un iterador a shared_ptr del objeto suficiente para eliminar el objeto de forma permanente y libre de la memoria? Parece estar eliminando el shared_ptr del contenedor.
  2. Actualmente, el contenedor allhosts tiene un índice de funcionamiento que se basa en la identificación del host. Si introduzco un segundo índice ordenado que llama a una función miembro (Host :: getAge()), donde la edad cambia a lo largo de la simulación, ¿el índice siempre se actualizará cuando me refiera a él?
  3. ¿Cuál es la diferencia entre usar la modificación de MultiIndex para modificar la antigüedad del objeto subyacente en comparación con el enfoque que muestro arriba?
  4. Estoy vagamente confundido acerca de lo que se supone/requiere que sea constante en MultiIndex.

Gracias de antemano.


actualización

Aquí está mi intento de conseguir el funcionamiento de modify sintaxis, en base a lo que veo en un impulso relacionado 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 
    } 
}; 

y luego en modifyHost, tendría hmap.modify(it,update_age). Incluso si por algún milagro esto resulta ser correcto, me encantaría algún tipo de explicación de lo que está sucediendo.

Respuesta

7

shared_ptr eliminará el objeto real Host en su destructor (si no hay otras instancias de shared_ptr). Todos los objetos en MultiIndex se consideran constantes. Para modificar el objeto, debe usar el método modify de MultiIndex. En ese caso, los índices serán actualizaciones si es necesario.

podría utilizar el siguiente funtor cambiar 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_; 
    }; 

luego usarlo como sigue:

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

Gracias de nuevo. Incluso después de estudiar su enlace, sigo teniendo problemas con la sintaxis de modificación. El uso de hmap.modify (it, incrementAge()) con Host :: incrementAge() provoca un error fuera del alcance. Veo algunos ejemplos que usan estructuras (cuando los elementos del contenedor son los objetos mismos) pero no puedo entender por qué mi código no funciona. – Sarah

+0

Actualicé mi respuesta para mostrar cómo usar 'modificar'. –

+0

Gracias, Kirill, eso es muy útil. (Tengo otras funciones miembro que toman entradas, y que necesitaré invocar con modify().) Todavía estoy confundido sobre qué hacer cuando estoy tratando de llamar a una función miembro que no toma entradas, sin embargo, ¿está mi código editado arriba? – Sarah

Cuestiones relacionadas