【问题标题】:Copy base class reference value to map with shared_ptr使用 shared_ptr 将基类引用值复制到映射
【发布时间】:2018-03-02 01:44:28
【问题描述】:

我有一个基类和派生类(BaseObj 和 Derived Obj),我需要一个字符串键映射,该映射具有指向对象的指针:

std::map<std::string, std::shared_ptr<BaseObj>

这里是复杂的:映射值需要在堆上,因为对象将超出范围,但是对象是通过引用传递给函数的:

void insert_in_map(std::string, const& BaseObj);

由于引用是对基类的引用,因此(据我所知)无法将底层值复制到堆并获取指向它的基指针。我能想到的唯一解决方案是更改函数原型以接受已在堆上分配对象的 shared_ptr。但是,我真的很想避免在所有调用者中创建 shared_ptr,尤其是因为必须将 shared_ptr 复制到地图中。

有什么想法吗?

【问题讨论】:

  • “但是,我真的很想避免在所有调用者中创建 shared_ptr,尤其是因为必须将 shared_ptr 复制到地图中。”你的推理是错误的,特别是因为 shared_ptr 假设被插入到地图中,你应该更改函数签名。但不清楚为什么需要shared_ptr。 unique_ptr 应该足够了

标签: c++ pointers dictionary reference shared-ptr


【解决方案1】:

有什么想法吗?

是的,您应该将函数签名更改为:

void insert_in_map(std::string, std::unique_ptr<BaseObj>);

所以这将清楚地表明函数获取对象的所有权。除非您确实需要共享所有权,否则您的地图可能也应该更改为 std::unique_ptr 而不是共享地图。在这种情况下,您可以将它们都更改为std::shared_ptr(这可能比将std::unique_ptr 转换为std::shared_ptr 内部函数更有效)。我会创建类型别名并在这两种情况下都使用它。

但是,我真的很想避免在所有调用者中创建 shared_ptr,尤其是因为必须将 shared_ptr 复制到地图中。

它不必被复制,它可以移动到地图中,所以你的推理很奇怪——你不应该拥有一个对象的所有权,通过 const 引用传递。

如果您无法更改函数签名,您可以将虚拟方法std::shared_ptr&lt;BaseObject&gt; clone() 添加到基类中并相应地覆盖。但这在你的情况下似乎是不合理的,因为你可以改变函数签名,你不想要一些奇怪的原因。

【讨论】:

  • 是否可以通过值将 unique_ptr 传递给函数,因为这会导致两个 unique_ptr 指向同一个地址?
  • 另外,我使用 shared_ptr 的原因是稍后需要从地图中检索指针,而不需要从地图中删除记录。所以这需要一个 shared_ptr 因为我相信一个 unique_ptr 不能存在于两个地方并映射到同一个地址。
  • 是的,可以按值传递,我建议采用这种方式。替代方法是通过右值引用传递。
  • 如果您需要共享所有权,是的,这是合理的,请记住它是有价格的,因此仅在必要时才应使用它。 std::unique_ptr 更轻量级。
猜你喜欢
  • 2015-06-24
  • 2021-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-04
相关资源
最近更新 更多