【问题标题】:How to obtain polymorphic behavior with unique pointers?如何获得具有唯一指针的多态行为?
【发布时间】:2018-12-02 09:53:36
【问题描述】:

在长时间的休息之后玩弄 C++。

我有一个 std::vector 的唯一指针,指向我迭代的对象,调用一个函数,该函数将派生 vector 中的对象的基类作为参数,如下所示:

for (auto const& object : objects)
{
    _process(object);
}

objects 在哪里:

std::vector<std::unique_ptr<Derived>>

我想了解如何强制执行多态行为来调用函数:

_process(std::unique_ptr<Base> base)

【问题讨论】:

  • 您不应该在循环通过vector 时尝试将unique_ptr&lt;Derived&gt; 转换为unique_ptr&lt;Base&gt;base 参数是按值传递的,并且会从vector 中获取指针的所有权。我只需将base 参数更改为原始Base* 指针,因为_process() 不应更改所有权,然后将其称为_process(object.get())
  • 我会使用_process(Base*); 并致电_process(object.get());
  • @RemyLebeau 您可以将unique_ptr&lt;Derived&gt; 转换为unique_ptr&lt;Base&gt;
  • 也就是说,我不明白这个问题。无论多态性如何,您都不能复制unique_ptr_process() 是什么,你想做什么?
  • @Barry 不转移指针的所有权

标签: c++ c++11 stl smart-pointers


【解决方案1】:

std::unique_ptr 代表所有权,因此无法复制。

这意味着_process(std::unique_ptr&lt;Base&gt; base) 是一个接收器,即它消耗对象(它可以销毁它或将它存储在某个地方,但调用者不再控制它)。要调用它,您必须使用 std::move:

_process(std::move(object))

这样你就明确地拒绝了对象的所有权并从你的容器中移除它——指针将被重置为nullptr

当然,这只能通过非const 引用来完成。

如果您不想转移所有权而只想对对象做点什么——_process 这个名字似乎暗示了——你应该传递常规的原始指针:

_process(Base* base);
...
for (auto const& object : objects)
{
    _process(object.get());
}

除了控制对象的生命周期之外,原始指针仍然适用于一切。

在这两种情况下(原始指针和unique_ptr),从Derived 隐式转换到Base 应该绝对没有问题。

【讨论】:

  • 如果您考虑销毁,这个答案会有所改善;需要虚拟 dtor 或类型擦除删除器才能使您的代码正确。
  • @Yakk-AdamNevraumont 我认为这个问题专门针对智能指针,并且 OP 知道多态破坏和相关问题。我想我会添加几个链接以防万一。
  • 它是“多态行为”的一部分,尤其是具有独特的指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 2017-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多