【问题标题】:Removing a unique pointer from an array of unique pointers从唯一指针数组中删除唯一指针
【发布时间】:2014-06-23 13:48:14
【问题描述】:

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

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

向量的初始化如下:

myVector.resize(MAX_OBJECTS,nullptr);

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

我还需要安全地将元素添加到向量中,而不使用 push_back 或 emplace_back。

提前致谢。

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

【问题讨论】:

  • 那么应该在哪里添加元素?第一个nullptr 空间?还是到特定的索引?
  • 如果你需要一个固定大小的数组,你可能想使用std::array&lt;&gt;
  • 为什么向量的大小不变很重要?
  • 数组中指针的顺序重要吗?您打算如何检测指针是否仍然存在?

标签: c++ pointers vector unique-ptr


【解决方案1】:

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

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

myVector[i].reset()

要将元素添加到特定索引(覆盖之前的索引),您可以使用 std::unique_ptr::reset() 并将新指针作为参数:

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

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

【讨论】:

  • std::unique_ptr.release() 不会调用对象的析构函数。我想你的意思是std::unique_ptr.reset()(无参数)
【解决方案2】:

看起来您想使用 std::array&lt;&gt; 而不是强制 std::vector&lt;&gt; 表现得像一个。

【讨论】:

    【解决方案3】:

    正如已经指出的,如果大小是固定的,您应该使用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
    

    【讨论】:

      【解决方案4】:

      你可以使用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&lt;unique_ptr&lt;MyObject&gt;, SIZE&gt; 而不是向量。但是,如果在编译时不知道 SIZE,那么您的代码就可以了。

      【讨论】:

        【解决方案5】:

        您可以使用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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-02
          • 2013-04-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多