首页 > 解决方案 > 使用单元素 STL 容器作为缓存?

问题描述

我有一个类(我们称之为它Class1),这个类的对象偶尔需要另一个类的对象(我们称之为它Class2)。的对象Class2构建起来很昂贵,所以我只想在真正需要时才构建它,然后将其保存为缓存以备将来在Class1.

一种可能性是有一个Class2*(或智能指针)数据成员,其中Class1最初是可能的。nullptrClass1

为什么不使用类似 Class1 的 STL 容器数据成员,std::vector或者std::unordered_map在开始时为空的,如果需要,将对象的对象Class2保存(通过使用emplace-like 成员函数构造它)作为容器中的唯一元素?我认为这具有更差的性能,但与构造对象所需的资源相比,它可能并没有那么糟糕Class2......

所以,我的问题提炼出来了:
使用单元素容器作为缓存的数据成员是个好主意吗?如果不是,为什么不呢?什么是好的选择?如果是,最好使用哪个容器?

感谢四位您的帮助和意见!

编辑:澄清如果一个对象Class1被复制会发生什么:缓存的对象应该被复制到新的对象中,或者新的缓存应该是空的,两者都很好。我不想要的是复制指向同一个对象的指针。

编辑 2:我应该在一开始就已经提到,代码到现在只使用 C++11 功能,如果它保持这样就好了。但我也很欣赏所有提到 C++14 和 C++17 特性的评论,因为它们通常很有趣且有用。

标签: c++

解决方案


您通常不会为此使用容器;虽然容器只有一个元素并没有什么问题,但我们通常使用它们,因为我们想要管理多个元素的集合,并且它们的设计围绕该功能展开。


那么,传统上,为了获得性能而不是表示意图,您需要某种“可选”对象,并且在过去new,您只需在需要时通过 -ing 类型的实例来实现它(否则保持空指针)。从 C++11 开始,您应该将std::unique_ptr其用于此目的,以解决“内存管理的常见困难”

如果您想复制您的类以深度复制缓存,只需将其放入m_cache(other.m_cache ? std::make_unique<TheType>(*other.m_cache) : nullptr)复制构造函数的初始化列表中!


在现代(自 C++17 起,甚至在您对 Boost 满意之前),您可以跳过动态分配(和深拷贝滑稽动作)并改用std::optional,这是当前的惯用解决方案。

实际上,您总是可以使用 Placement-new和 a来实现这一点bool,但是很高兴有一个预先打包的解决方案来为我们完成所有这些工作。

请注意,由于非动态分配,该解决方案将始终占用sizeof(TheType)+sizeof(bool)空间,无论您的缓存是否正在使用。


推荐阅读