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

问题描述 投票:0回答:1

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

有任何想法吗?

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

© www.soinside.com 2019 - 2024. All rights reserved.