使用类的枚举成员作为存储该类实例的std::map键的设计咨询
方案选型建议
首先根据类A的使用场景分两种情况判断:
情况1:类A需要脱离类B独立使用,且自身逻辑需要访问类型标识
这种场景下保留A内部的type成员是合理的,所谓的「冗余」是为了保证类A的内聚性付出的合理成本,只需要解决键值与成员不一致的风险即可:
- 把A的构造函数设置为私有/保护,将类B设为友元,仅允许类B在插入元素时统一构造A实例,构造时传入的Type值同时作为map的键和A的
type成员初始值,从根源避免两者不一致 - A的
type成员仅对外提供只读getter,不开放修改接口,避免运行时被意外修改导致数据不一致
示例代码参考:
class A { friend class B; public: enum class Type { Type1, Type2, Type3 }; Type get_type() const { return type; } private: Type type; // 仅允许友元类B构造 explicit A(Type t) : type(t) {} // 其他业务成员... }; class B { private: std::map<A::Type, A> components; public: void add_component(A::Type t) { // 保证键和内部type完全一致 components.emplace(t, A(t)); } const A* get_component(A::Type t) const { auto it = components.find(t); return it != components.end() ? &it->second : nullptr; } };
情况2:类A本身不需要感知自身类型,Type仅作为类B的索引标识
这种场景下完全可以把Type从A的定义中移除,仅作为map的键存在,没有任何冗余,也符合单一职责原则:类型索引的职责归属于容器类B,和类A的自身逻辑无关。
如果你的Type枚举值是连续、范围固定的,还可以把std::map替换为std::array<A, ENUM_MAX_COUNT>,比map的访问速度更快、内存开销更低。
额外优化建议
如果不同Type对应的A实例逻辑差异较大,也可以考虑把A改为多态基类,不同类型对应不同的子类实现,配合工厂模式构造实例,避免用枚举标记类型的硬编码逻辑。
内容的提问来源于stack exchange,提问作者SimStil
相关产品推荐
相关产品推荐

