如何构建一个Map,其中Key是一个抽象基类(而不是Value)

时间:2018-05-04 18:17:01

标签: c++ collections

我正在尝试构建一个对象映射,这些对象是各种派生类的实例,基类是抽象的:

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*指针的工作正常,但是地图的散列算法会比较指针,而不是找不到匹配的对象
  • 我没有看到覆盖=运算符的方法(实际上不可能有一个,因为散列算法适用于参数,这是一个指针 - 我必须覆盖散列算法本身以取消引用指针。
  • 请注意enter image description here不重复 - 它会讨论 Value ;我需要抽象基类作为 Key ,所以我可以 find()它。

换句话说,问题是:
如何构建对象映射(以及稍后搜索它们),其中这些对象是来自公共基类的不同派生类的实例?

1 个答案:

答案 0 :(得分:1)

是的,你的第二种选择是不可能的。但你的第一个是!标准库容器允许您使用自定义散列函数,您可以利用它。

此外,您无论如何都需要提供自定义哈希函数,因此它不应该是一个问题。你还提到你想要能够正确搜索它们吗?好吧,标准库也允许你自定义 ,你可以提供一个密钥相等对象,它可以比较底层对象而不是指针。

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;