2010-04-16 118 views
6

我想在我的模擬中使用Boost MultiIndex容器。我對C++語法的瞭解非常薄弱,我擔心我沒有正確地從容器中刪除元素或將其從內存中刪除。我也需要修改元素,我也希望在這裏確認語法和基本原理。刪除和修改Boost MultiIndex容器中的元素

// 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. 在多指標容器shared_ptrs的allHostsHost對象,是在一個迭代對象的shared_ptr的足夠永久刪除該對象並釋放它從內存中調用allHosts.erase(it)?它似乎是從容器中刪除shared_ptr。
  2. allhosts容器目前有一個依賴於主機ID的功能索引。如果我引入一個調用成員函數(Host :: getAge())的有序第二個索引,那麼在模擬過程中年齡發生變化時,索引始終會在我引用時更新?
  3. 使用MultiIndex的修改來修改底層對象的年齡與上面顯示的方法之間有什麼區別?
  4. 我對於在MultiIndex中假定/要求保持不變的模糊不清。

在此先感謝。


更新

這裏是我試圖讓modify語法工作的基礎上,我在一個相關的升壓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 
    } 
}; 

,然後在modifyHost,我有hmap.modify(it,update_age)。即使通過一些奇蹟,事實證明這是正確的,但我喜歡對發生的事情進行某種解釋。

回答

7

shared_ptr將在其析構函數中刪除實際的Host對象(如果沒有其他實例shared_ptr)。 MultiIndex中的所有對象都被認爲是常量。要修改對象,您應該使用MultiIndex的方法modify。在這種情況下,索引將在必要時更新。

您可以使用下面的函子來改變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 
+0

謝謝。即使在研究你的鏈接之後,我仍然遇到了修改語法的問題。使用hmap.modify(it,incrementAge())和Host :: incrementAge()會導致超出範圍的錯誤。我看到一些使用結構的例子(當容器元素是對象本身時),但無法追蹤爲什麼我的代碼無法工作。 – Sarah 2010-04-16 17:16:42

+0

已更新我的回答,以顯示如何使用'modify'。 – 2010-04-16 17:38:12

+0

謝謝,基里爾 - 這非常有用。 (我有其他的成員函數需要輸入,而我需要用modify()來調用)。當我試圖調用一個不需要輸入的成員函數時,我仍然困惑於該怎麼做,雖然 - 我的編輯代碼在右上方? – Sarah 2010-04-16 17:47:00