2010-04-16 20 views
6

Tôi đang cố gắng sử dụng vùng chứa Tăng cường MultiIndex trong mô phỏng của mình. Kiến thức của tôi về cú pháp C++ rất yếu, và tôi lo ngại rằng tôi không loại bỏ đúng một phần tử khỏi vùng chứa hoặc xóa nó khỏi bộ nhớ. Tôi cũng cần phải sửa đổi các yếu tố, và tôi đã hy vọng để xác nhận cú pháp và triết lý cơ bản ở đây quá.Xóa và sửa đổi các thành phần trong Tăng cường 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... 
} 

Câu hỏi của tôi là

  1. Trong container MultiIndex allHosts của shared_ptrs để Host đối tượng, đang kêu gọi allHosts.erase(it) trên một iterator để shared_ptr của đối tượng, đủ để xóa các đối tượng vĩnh viễn và miễn phí nó từ bộ nhớ? Dường như xóa shared_ptr khỏi vùng chứa.
  2. Vùng chứa allhosts hiện có một chỉ mục hoạt động dựa trên ID của máy chủ lưu trữ. Nếu tôi giới thiệu một chỉ số thứ hai có thứ tự gọi các hàm thành viên (Host :: getAge()), khi độ tuổi thay đổi trong quá trình mô phỏng, thì chỉ mục luôn được cập nhật khi tôi đề cập đến nó?
  3. Sự khác biệt giữa việc sử dụng sửa đổi của MultiIndex để sửa đổi độ tuổi của đối tượng bên dưới so với cách tiếp cận tôi hiển thị ở trên là gì?
  4. Tôi mơ hồ nhầm lẫn về những gì được giả định/bắt buộc phải không đổi trong MultiIndex.

Xin cảm ơn trước.


Cập nhật

Đây là nỗ lực của tôi để có được làm việc modify cú pháp, dựa trên những gì tôi nhìn thấy trong một Boost liên quan 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 
    } 
}; 

và sau đó trong modifyHost, tôi muốn có hmap.modify(it,update_age). Ngay cả khi một phép lạ nào đó hóa ra là đúng, tôi rất thích một số lời giải thích về những gì đang xảy ra.

Trả lời

7

shared_ptr sẽ xóa đối tượng Host thực trong trình phá hủy của nó (nếu không có trường hợp nào khác là shared_ptr). Tất cả các đối tượng trong MultiIndex đều được coi là không đổi. Để sửa đổi đối tượng, bạn nên sử dụng phương thức modify của MultiIndex. Trong trường hợp đó các chỉ mục sẽ được cập nhật nếu cần thiết.

Bạn có thể sử dụng các functor sau để thay đổi age lĩnh vực:

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

    private: 
    int age_; 
    }; 

Sau đó, sử dụng nó như sau:

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

Cảm ơn một lần nữa. Ngay cả sau khi nghiên cứu liên kết của bạn, tôi vẫn gặp sự cố với cú pháp sửa đổi. Sử dụng hmap.modify (nó, incrementAge()), với Host :: incrementAge(), gây ra lỗi ngoài phạm vi. Tôi thấy một số ví dụ sử dụng cấu trúc (khi các phần tử thùng chứa là các đối tượng của chính chúng) nhưng không thể theo dõi tại sao mã của tôi không hoạt động. – Sarah

+0

Cập nhật câu trả lời của tôi để hiển thị cách sử dụng 'sửa đổi'. –

+0

Cảm ơn, Kirill - điều đó rất hữu ích. (Tôi có các hàm thành viên khác có đầu vào, và rằng tôi sẽ cần phải gọi với modify().) Tôi vẫn còn bối rối về những việc cần làm khi tôi chỉ cố gắng gọi một hàm thành viên không có đầu vào, mặc dù - là mã chỉnh sửa của tôi ở trên phải không? – Sarah

Các vấn đề liên quan