【问题标题】:How to retrieve a reference from a boost ptr_vector?如何从 boost ptr_vector 中检索引用?
【发布时间】:2010-09-21 22:38:28
【问题描述】:

我有两个类:一个 Object 类和一个 ObjectManager 类。 ObjectManager 类通过 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 保留所有权,但我也希望其他类能够获得对该对象的引用,根据正在发生的事情对该对象使用调用方法,然后继续。

【问题讨论】:

    标签: c++ boost ptr-vector


    【解决方案1】:

    将您的容器转换为使用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();
      }
    };
    

    顺便说一句 - 更喜欢 ++itit++ 以避免额外的构造,如果容器变大,不要使用这样的匹配 - 切换到 std::map&lt;int, ObjectPtr&gt;m_id 作为键,或 std::set 与适当定义的less 函数。

    如果我过于迂腐,我会建议将你的 find 循环替换为对 std::find_if 的调用,并使用与 Object::m_id 匹配的谓词...

    【讨论】:

    • 啊,谢谢史蒂夫!另外,如果您不介意回答,当您说“如果容器变大时不要使用这样的匹配”时,您指的是性能问题吗?
    • @jbaez :是的,这是与性能相关的 - 像这样的匹配将是 O(n) - 搜索地图(二叉树)是 O(log n)
    【解决方案2】:

    您无法返回 shared_ptr,因为该对象最初不是作为共享对象创建的 - 引用计数会是多少?

    但是,您可以很容易地返回 Object*:

    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;
          }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多