I'm trying to use a Boost MultiIndex container in my simulation. My knowledge of C++ syntax is very weak, and I'm concerned I'm not properly removing an element from the container or deleting it from memory. I also need to modify elements, and I was hoping to confirm the syntax and basic philosophy here too.
// 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...
}
My questions are
allHosts
of shared_ptrs to Host
objects, is calling allHosts.erase( it )
on an iterator to the object's shared_ptr enough to delete the object permanently and free it from memory? It appears to be removing the shared_ptr from the container.allhosts
container currently has one functioning index that relies on the host's ID. If I introduce an ordered second index that calls on a member function (Host::getAge()), where the age changes over the course of the simulation, is the index always going to be updated when I refer to it?Thanks in advance.
Update
Here's my attempt to get the modify
syntax working, based on what I see in a related Boost 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
}
};
and then in modifyHost
, I'd have hmap.modify(it,update_age)
. Even if by some miracle this turns out to be right, I'd love some kind of explanation of what's going on.
shared_ptr
will remove actual Host
object in its destructor (if there is no other instances of shared_ptr
). All objects in MultiIndex are considered constant. To modify the object you should use method modify
of MultiIndex. In that case indexes will be updates if necessary.
You could use the following functor to change age
field:
struct change_age
{
change_age(int age) : age_(age) {}
void operator()(boost::shared_ptr<Host> h) // shared_ptr !!!
{
h->age = age_;
}
private:
int age_;
};
Then use it as follows:
testHosts.modify( it, Host::change_age( 22 ) ); // set age to 22
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With