首页 > 解决方案 > 如何构建 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 数据会丢失。到目前为止,我明白为什么它不能工作。

但是我怎样才能制作这样的地图呢?

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

标签: c++collections

解决方案


是的,你的第二个选项是不可能的。但你的第一个是!标准库容器允许您使用自定义散列函数,您可以使用它来发挥自己的优势。

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

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;

推荐阅读