跨容器共享对象的最佳方式是什么?

What's the best way of sharing object across containers?

本文关键字:最佳 方式 是什么 对象 共享      更新时间:2023-10-16

在我的一个项目中,我遇到了一种情况,我想在内存中创建对象的索引。主要索引可以使用不同的关键字,而次要索引将使用一些其他元素作为关键字。如果我使用std::map作为进行主索引

std::map<string, Object>

那么使用另一个容器(同样是std::map,例如考虑到所有对象都是唯一的)来存储辅助索引的引用/指针,而不制作对象的额外副本的最佳方式是什么?

  • 使用存在悬挂指针或引用风险的原始指针或引用(我知道,理想情况下,当对象从主索引中删除时,还应该注意将其从辅助索引中删除,但当主索引的容器内部调整时,辅助索引中的指针/引用会失效吗?)

    std::map<string, const Object*>

  • 或者在主索引中使用shared_ptr和weak_ptr的辅助索引的组合std::map<string, std::shared_ptr<Object>> // primary index std::map<string, std::weak_ptr<Object>> // secondary index

我知道这两种方法都有利弊。特别是我不想失去直接在主容器中插入对象的灵活性,但我也不希望辅助索引再次复制对象。仅将智能指针用于辅助索引的困难在于,它们不会拥有Object。

提前感谢您的帮助。

将对象放在某个容器中。根据添加/删除对象的频率,您可能需要考虑使用一个不会使对其元素的引用无效的容器,如std::liststd::deque

然后,对于地图,只需使用引用(即使用std::reference_wrapper)来引用对象(或其任何成员)。

封装后端存储和索引,以便无论何时添加或删除对象,都可以从索引中删除无效引用以及添加任何新引用。

这样,你只需要存储一次对象,然后使用智能指针四处走动。显然,只有当你真正拥有对象并控制它们的生存期,并且你可以保持索引的封装(以保持它们的更新)时,这才会起作用。