c++ - 如何构建 Key 是抽象基类(不是 Value)的 Map
问题描述
我正在尝试构建一个对象映射,这些对象是各种派生类的实例,基类是抽象的:
class B {void SomeMethod() = 0;}; //abstract
class D1 : public B {...}; // not abstract
class D2 : public B {...}; // not abstract
std::unordered_map<B,int> myMap;
D1 * d1 = new D1();
D2 * d2 = new D2();
myMap.insert({*d1,5}
myMap.insert({*d2,8}
这不起作用,因为地图考虑*d1
了一个B
对象,并尝试在地图内复制构造它。即使它可以工作,它也会对对象进行切片,并且 D1 数据会丢失。到目前为止,我明白为什么它不能工作。
但是我怎样才能制作这样的地图呢?
- 存储
B*
指针反而可以正常工作,但是映射的散列算法比较指针,而不是对象,它不会找到匹配项 - 我没有看到覆盖 = 运算符的方法(实际上不可能有,因为散列算法适用于参数,它是一个指针 - 我必须覆盖散列算法本身才能取消引用指针。
- 请注意,抽象基类的 C++ 集合不是重复的——它谈论的是Value;我需要抽象基类作为Key,所以我可以find()它。
换句话说,问题是:
如何构建对象映射(然后搜索它们),其中这些对象是来自公共基类的不同派生类的实例?
解决方案
是的,你的第二个选项是不可能的。但你的第一个是!标准库容器允许您使用自定义散列函数,您可以使用它来发挥自己的优势。
此外,无论如何您都需要提供自定义哈希函数,所以这不应该是一个问题。您还提到您希望能够搜索它们吗?好吧,标准库也允许您自定义它,您可以提供一个键相等对象来比较底层对象而不是指针。
struct FooPtrHash {
std::size_t operator()(const Foo *Value) const {
return Value->Value;
}
};
struct FooPtrEquality {
bool operator()(const Foo *Lhs, const Foo *Rhs) const {
return *Lhs == *Rhs;
}
};
std::unordered_map<Foo*, int, FooPtrHash, FooPtrEquality> Map;
推荐阅读
- javascript - 反应 - .map 使道具未定义
- python - 如何在 numpy 数组中查找特定值?
- github - 有没有办法查看 GitHub 事件?
- jms - 同一会话/主题上的 qpid 生产者和消费者?
- flutter - 如何在颤动的屏幕开始处添加动画显示
- c# - .NET Core 3 API 模型将复杂类型与 Angular 10 绑定
- reason - 如何在 ReScript 中将动态值设置为 Js.t 键?
- python - Flask-RESTPlus:如何在嵌套 API 模型中获取查询 sqlite 数据库的结果?
- git - 意外删除bin文件夹后恢复Gitlab
- php - php - 通过关键条件创建新数组并用另一个数组值填充