【问题标题】:How to add objects to a std::vector<unique_ptr<obj>>?如何将对象添加到 std::vector<unique_ptr<obj>>?
【发布时间】:2023-03-04 08:40:01
【问题描述】:

问题:
如何将对象添加到 std::vector&lt;unique_ptr&lt;obj&gt;&gt;?

我有一堂课,这就是我尝试要做的事情...
下面,我尝试在我的向量中使用std::unique_ptr&lt;Ball&gt;,因为我认为这将是最简单的。

class Ball {
public:
    Ball(float x, float y);
    std::vector<std::unique_ptr<Ball>> object;
    // other declarations below...
};


我在这里尝试push_back新元素:

Ball ball { 0, 0 };
for (size_t i { 0 }; i != 50; ++i) {
ball.object.push_back(new Ball { 0, 0 });
//        ^ here is the error
}

我不明白我遇到的错误。
错误:
error C2664: 'void std::vector&lt;std::unique_ptr&lt;Ball,std::default_delete&lt;_Ty&gt;&gt;,std::allocator&lt;std::unique_ptr&lt;_Ty,std::default_delete&lt;_Ty&gt;&gt;&gt;&gt;::push_back(const std::unique_ptr&lt;_Ty,std::default_delete&lt;_Ty&gt;&gt; &amp;)' : cannot convert argument 1 from 'Ball *' to 'std::unique_ptr&lt;Ball,std::default_delete&lt;_Ty&gt;&gt; &amp;&amp;'

【问题讨论】:

  • 一个球拥有一堆球?这是一个奇怪的设计。
  • 使用emplace_back 将参数传递给unique_ptr 的构造函数。
  • @remyabel,谢谢,解决了。
  • unique_ptr 的转换构造函数,它拥有原始指针 is marked explicit 的所有权。因此,您必须显式地执行从原始指针到unique_ptr的转换。
  • @dyp 从技术上讲,如果它是显式的,它就不是一个转换构造函数:)

标签: c++ c++11 vector unique-ptr raii


【解决方案1】:

当你使用push_back时,你需要创建一个unique_ptr。由于输入过多且容易出错,您可以使用emplace_back 来转发您的球对象。在 C++14 中,make_unique 可用并且应该是首选。

for (size_t i { 0 }; i != 50; ++i) {
    ball.balls.emplace_back(new Ball { 0, 0 });
}

【讨论】:

  • 您的解决方案也容易出错,如果emplace_back 尝试重新分配向量并且失败,它不会删除指针。即使使用emplace_back,您仍然应该创建一个临时的unique_ptr
【解决方案2】:

如果您使用vector&lt;unique_ptr&lt;T&gt;&gt;,则无需显式释放内存,因为它会在调用封闭类的析构函数时自动释放。

你必须创建一个unique_ptr&lt;Ball&gt;对象,你不能直接传递一个Ball*。最好的解决方案是使用std::make_unique&lt;Ball&gt;(0,0)。

【讨论】:

  • 不过,这是针对 C++14 的。
  • 问题标题与正文不匹配,您回答了标题。现在标题已更改以匹配正文,您的问题没有回答。
【解决方案3】:

既然您说您正在寻找最简单的方法,请使用std::vector&lt;Ball&gt; 而不是std::vector&lt;std::unique_ptr&lt;Ball&gt;&gt;。无需增加指针所有权的复杂性。

【讨论】:

  • 这在技术上是 UB,因为不能保证 std::vector 支持不完整的类型......但是。
猜你喜欢
  • 2021-11-23
  • 2014-11-23
  • 2021-11-26
  • 2019-11-07
  • 2018-02-02
  • 1970-01-01
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
相关资源
最近更新 更多