从唯一指针数组中删除唯一指针

时间:2014-06-23 13:48:15

标签: c++ pointers vector unique-ptr

我试图创建一个维护固定大小的托管对象唯一指针向量的类,如下所示:

std::vector<std::unique_ptr<Myclass>> myVector;

矢量初始化如下:

myVector.resize(MAX_OBJECTS,nullptr);

现在,我需要的是,能够根据请求删除一个存储的唯一指针,而不会影响向量的大小。

我也需要安全地向矢量添加元素,而不使用push_back或emplace_back。

提前致谢。

编辑:我希望矢量具有恒定的大小,因为我希望能够在恒定时间内添加和删除元素。

5 个答案:

答案 0 :(得分:1)

您希望使用std::array<>而不是强制std::vector<>表现得像一个人。

答案 1 :(得分:1)

正如已经指出的那样,如果尺寸固定,你应该使用std::array 例如:

std::array<std::unique_ptr<YourType>, MAX_OBJECTS> myVector;

然后您可以删除或添加这样的新指针。

for(auto& v : myVector)
    if(v && predicate)
        v.reset();// or v.reset(ptr) to set a new one

答案 2 :(得分:1)

如果您想要固定大小的矢量,请使用std::array

要删除索引中的unique_ptr,您可以使用std::unique_ptr::reset()

myVector[i].reset()

要将元素添加到特定索引(覆盖之前的内容),可以将std::unique_ptr::reset()与新指针一起用作参数:

myVector[i].reset(new Myptr(myparameter));

阅读参考资料也可能有所帮助:

答案 3 :(得分:1)

您可以使用STL算法std :: remove,如下所示:

// all items that should be removed will be the range between removeAt and end(myVector)
auto removeAt = std::remove_if(begin(myVector), end(myVector), 
                               ShouldRemovePredicate);

// reset all items that should be removed to be nullptr
for(auto it = removeAt; it != end(myVector); ++it)
    it->reset(); 

此外,如果在编译时已知大小,我建议使用std::array<unique_ptr<MyObject>, SIZE>而不是向量。但是,如果在编译时不知道SIZE,那么您的代码就可以了。

答案 4 :(得分:1)

您可以使用std::array代替std::vector,因为您事先知道了元素的数量,您可以添加和删除元素,如下例所示:

#include <iostream>
#include <memory>
#include <array>

class foo {
  std::size_t id;
  public:
  foo() : id(0) {}
  foo(std::size_t const _id) : id(_id) {}
  std::size_t getid() const { return id; }
};

auto main() ->int {
  // construct an array of 3 positions with `nullptr`s
  std::array<std::unique_ptr<foo>, 3> arr;

  // fill positions
  std::unique_ptr<foo> p1(new foo(1));
  arr[0] = std::move(p1);
  std::unique_ptr<foo> p2(new foo(2));
  arr[1] = std::move(p2);
  std::unique_ptr<foo> p3(new foo(3));
  arr[2] = std::move(p3);

  // print array
  for(auto &i : arr) if(i != nullptr) std::cout << i->getid() << " ";
  std::cout << std::endl;

  // reset first position (i.e., remove element at position 0)
  arr[0].reset();

  // print array
  for(auto &i : arr) if(i != nullptr) std::cout << i->getid() << " ";
  std::cout << std::endl;

  return 0;
}

LIVE DEMO