2010-09-21 69 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; 
     } 
    }