【问题标题】:Using class member as key in a std::map of said class使用类成员作为所述类的 std::map 中的键
【发布时间】:2021-11-15 00:53:59
【问题描述】:

我有一个带有枚举类成员变量的类,它旨在用作实例化对象的描述,永远不会有两个相同类型的实例化对象,例如:

class A
{
   enum class Type { Type1, Type2, ...} type;
}

我想将所有实例化的对象存储在一个集合中,以便根据类型轻松访问,所以我认为映射是合适的:

class B
{
   std::map<A::Type, A> components;
}

但是,有些事情告诉我这不是很好的设计,因为我实际上是在复制相同的数据,即使用类 (A) 成员变量 (type) 作为指向值的键 ( A) 类的对象,它也包含相同的信息。另一种选择是不将枚举用作 class A 成员变量,而是在 class B 中定义该枚举并仅将其用作键。 有什么建议吗?

【问题讨论】:

  • std::set&lt;A, CustomComparerOnType&gt;? (如果实例是不可变的)。
  • 没有错。更多的是关于你有什么用例。
  • 建议:不要过多地思考什么才是伟大的设计。设计服务于某些目的,如果您需要两次存储密钥,那么它有什么问题呢?您可以考虑使用std::vector&lt;A&gt; 作为替代方案,但您会错过map 的所有便利
  • @appleapple 它可以有效地存储代表成本(数量、数量等)的组件(A 类)的集合,因此 B 类将用于有效地执行诸如汇总所有组件的成本之类的操作,但我仍然需要一种方法来访问单个组件的成本,因此映射将是理想的,而不是将对象存储在 std::vector 中并使用 if 语句遍历它以获取实际的组件类型。
  • @463035818_is_not_a_number 感谢您的建议-我肯定会想太多-正如我在对apple apple的评论中提到的那样,我想要该地图,因为我希望轻松访问集合中的各个对象,但是否则我会使用向量。

标签: c++ oop architecture


【解决方案1】:

让我们考虑地图的主要特征

  • 唯一键
  • 关于键的排序
  • 键是const,值不是
  • 键与映射值分开存储

您的要求与最后一个项目符号形成对比,因此现在您可以考虑可以与其他项目做出哪些妥协。

  • std::set&lt;A,CustomComparator&gt;

使用自定义比较器,您可以确保可以存储在值中的唯一键,并且排序可以与地图相同。但元素是const。您可以使用 mutable 但这会绕过 const 正确性,应谨慎使用。

  • std::vector&lt;A&gt;

这是最灵活的,但您需要手动处理从地图中获得的几乎所有内容。如果您只填充一次向量然后只访问元素,这可能是可行的,因为您需要检查唯一性并对元素进行一次排序。

  • 一些非标准容器

Jarod42 建议增强侵入性 set。可能还有其他符合您需求的非标准容器。

  • 留在std::map&lt;A::type,A&gt;

如果密钥只是单个枚举值,那么将密钥存储两次是一种简单的解决方案,但需要一些成本,但允许您在要使用的容器时使用 map

  • 首先不将键存储在 mapped_values 中

当 mapped_values 仅存储在 map 中而不在 map 之外使用时,这实际上是最干净的解决方案。当您仍然需要 mapped_values 以及地图外的键时,您可以使用std::pair&lt;type::A,A&gt;

【讨论】:

  • 感谢您的全面回复。根据您对其他选项的比较,我倾向于使用最后建议的解决方案。
猜你喜欢
  • 1970-01-01
  • 2013-10-03
  • 2018-01-24
  • 2020-11-30
  • 1970-01-01
  • 2011-06-23
  • 1970-01-01
  • 2014-08-06
  • 2011-05-08
相关资源
最近更新 更多