c ++ 11成员函数从unique_ptr的向量返回原始指针的向量

my_*_*ion 10 c++ c++11

我开始使用c ++ 11功能,我喜欢使用智能指针只拥有对象.这是我的班级:

class MyClass {
  public:
    vector<MyObject*> get_objs() const;

  private:
    vector<unique_ptr<MyObject>> m_objs;
};
Run Code Online (Sandbox Code Playgroud)

语义是MyClass拥有一系列MyObject通过make_unique()创建的.get_objs()返回原始指针的向量,以便各种调用者更新对象.因为那些调用者不拥有对象,所以函数不返回vector<unique_ptr>.

但这意味着我需要get_objs()像这样实现:

vector<MyObjects*> MyClass::get_objs() const
{
  vector<MyObjects*> ret;
  for (auto obj : my_objs) {
    ret.push_back(obj->get());
  }
  return ret;
}
Run Code Online (Sandbox Code Playgroud)

get_objs()每次有一个开销来构造这个原始指针向量时,我会经常调用我的问题.

我能在这做些什么吗?如果没有c ++ 11技巧来节省开销,我应该首先使用type vector<MyObject*>for m_objs

UPDATE 1
Run Code Online (Sandbox Code Playgroud)

使用Jonathan Wakely的解决方案operator[]改进了我的解决方案,以便调用者可以直接访问单个对象.

还有其他解决方案吗?我不介意去所有的地方打电话,get_objs(),但想看看是否有更好的解决方案.

另一个注意事项 - 我不能使用BOOST,只是我必须忍受的一些限制.

Jon*_*ely 6

首先,您可以使用ret.reserve(m_objs.size())预分配正确数量的元素.

或者,不要为调用者返回一个向量直接迭代的向量,而是公开类似向量的接口:

class MyClass {
  public:
    struct iterator;
    iterator begin();
    iterator end();
    MyObject* operator[](size_t n) { return m_objs[n].get(); }

  private:
    vector<unique_ptr<MyObject>> m_objs;
};
Run Code Online (Sandbox Code Playgroud)

这允许调用者直接修改对象,而不是获取指针容器.

  • 为什么`operator []`返回一个指针,为什么没有它的`const`变体. (2认同)

Yak*_*ont 5

class MyClass {
  public:
   std::vector<std::unique_ptr<MyObject>> const& get_objs() const {
     return m_objs;
   }

  private:
    std::vector<std::unique_ptr<MyObject>> m_objs;
};
Run Code Online (Sandbox Code Playgroud)

aconst std::unique_ptr<MyObject>&不能窃取所有权,并且与 a 不同std::unique_ptr<const MyObject>。Aconst std::vector<std::unique_ptr<MyObject>>&只能授予const对其数据的访问权限。

我会这样做:

class MyClass {
  public:
   std::span<std::unique_ptr<MyObject> const> get_objs() const {
     return {m_objs.begin(), m_objs.end()};
   }

  private:
    std::vector<std::unique_ptr<MyObject>> m_objs;
};
Run Code Online (Sandbox Code Playgroud)

它隐藏了“我将它存储在一个向量中”的实现细节,同时暴露了“我正在连续存储它”。

之前,span如果您有预算,我建议您找到或编写自己的类型。它们非常有用。

  • +1,我认为值得一提的是,不能从 const 向量中的 `const unique_ptr&lt;MyObject&gt;` 元素中窃取所有权,但是使用 `get()` 你仍然可以从它们获取非常量的 `MyObject*`按照 OP 的要求更新对象。 (2认同)