2010-09-21 81 views
2

我有兩個類:一個對象類和一個ObjectManager類。 ObjectManager類通過ptr_vector容器存儲「對象」。在某些情況下,我需要檢索對這些存儲指針的引用,以對它們執行單獨的操作。我會怎麼做呢?如何從boost ptr_vector檢索參考?

可編譯僞代碼:

#include <boost/ptr_container/ptr_vector.hpp> 
#include <boost/shared_ptr.hpp> 

class Object 
{ 
public: 
    int m_Id; 
    Object(int id) : m_Id(id) { } 
}; 

class ObjectManager 
{ 
private: 
    typedef boost::shared_ptr<Object> ObjectPtr; 
    typedef boost::ptr_vector<Object> ObjectVectorPtr; 
    typedef ObjectVectorPtr::iterator ObjectIt; 

    ObjectVectorPtr vector_; 

    void AddObject(Object *obj) { 
    vector_.push_back(obj); 
    } 

    ObjectPtr FindObject(int id) { 
    for (ObjectIt it = vector_.begin(); it != vector_.end(); it++) { 
     if (it->m_Id == id) { 
     // Found the object...How to return a shared_ptr reference to it? 
     // The line below is invalid, obviously: 
     // cannot convert parameter 1 from 'Object' to 'const boost::shared_ptr<T> &' 
     return *it; 
     } 
    } 

    // We could not find anything. 
    return ObjectPtr(); 
    } 
}; 

基本上我想要的ObjectManager保留所有權,但我也希望其他類能獲取對象的引用,這取決於那是什麼物體上使用的調用方法繼續前進,繼續前進。

回答

2

轉換你的容器使用shared_ptr作爲成員:

#include <boost/ptr_container/ptr_vector.hpp> 
#include <boost/shared_ptr.hpp> 
#include <vector> 

class Object 
{ 
public: 
    int m_Id; 
    Object(int id) : m_Id(id) { } 
}; 

class ObjectManager 
{ 
private: 
    typedef boost::shared_ptr<Object> ObjectPtr; 
    typedef std::vector<ObjectPtr> ObjectVectorPtr; 
    typedef ObjectVectorPtr::iterator ObjectIt; 

    ObjectVectorPtr vector_; 

    void AddObject(ObjectPtr& obj) { 
    vector_.push_back(obj); 
    } 

    ObjectPtr FindObject(int id) { 
    for (ObjectIt it = vector_.begin(); it != vector_.end(); ++it) { 
     if (it->get()->m_Id == id) { 
     // Found the object - return a shared_ptr reference to it 
     return ObjectPtr(*it); 
     } 
    } 

    // We could not find anything. 
    return ObjectPtr(); 
    } 
}; 

順便說一句 - 喜歡++it VS it++避免額外建設,如果容器變大,不要使用這樣的匹配 - 切換到std::map<int, ObjectPtr>,使用m_id作爲關鍵字,或者使用std::set,使用適當定義的less功能。

如果我被超迂腐,我建議通過調用替換您發現環路std::find_if,與上Object::m_id匹配的斷言......

+0

啊,謝謝,史蒂夫!另外,如果你不介意回答,當你說「如果容器變大,不要使用這種匹配」,你是指性能問題嗎? – jbaez 2010-09-21 23:08:13

+0

@ jbaez:是的,這是perf-related - 這樣的匹配將是O(n) - 搜索地圖(二叉樹)是O(log n) – 2010-09-21 23:11:57

0

你不能返回一個shared_ptr,因爲最初沒有將對象創建爲共享對象 - 引用計數甚至會是什麼?

你可以,但是,返回一個對象*很容易:

Object* FindObject(int id) { 
    for (ObjectIt it = vector_.begin(); it != vector_.end(); it++) { 
     if (it->m_Id == id) { 
     // Found the object...How to return a shared_ptr reference to it? 
     // The line below is invalid, obviously: 
     // cannot convert parameter 1 from 'Object' to 'const boost::shared_ptr<T> &' 
     return &*it; 
     } 
    }