使用shared_ptr将基类引用值复制到映射

时间:2018-03-02 01:44:29

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

我有一个基类和派生类(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复制到地图中。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

  

有什么想法吗?

是的,您应该将功能签名更改为:

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<BaseObject> clone()添加到基类中并相应地重写。但是在你的情况下这似乎是不合理的,因为你可以改变功能签名,你不希望出于一些奇怪的原因。