抽象类作为std::map键
C++ Abstract Class as std::map key
我有一个这样的类层次结构:
struct Vehicle {
virtual string model() = 0; // abstract
...
}
struct Car : public Vehicle {...}
struct Truck : public Vehicle {...}
我需要保留一个std::map
,其中包含我获得的关于Vehicle
实例的一些信息:
std::map<Vehicle, double> prices;
但是我得到以下错误:
/usr/include/c++/4.2.1/bits/stl_pair.h: In instantiation of ‘std::pair<const Vehicle, double>’:
/usr/include/c++/4.2.1/bits/stl_map.h:349: instantiated from ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = Vehicle, _Tp = double, _Compare = std::less<Vehicle>, _Alloc = std::allocator<std::pair<const Vehicle, double> >]’
test.cpp:10: instantiated from here
/usr/include/c++/4.2.1/bits/stl_pair.h:73: error: cannot declare field ‘std::pair<const Vehicle, double>::first’ to be of abstract type ‘const Vehicle’
Model.hpp:28: note: because the following virtual functions are pure within ‘const Vehicle’:
Model.hpp:32: note: virtual string Vehicle::model()
所以你不能使用抽象类作为std::map
键。据我所知,这是因为映射复制它们的键(通过复制构造函数或赋值操作符),这将意味着实例化一个抽象类(Vehicle
)。而且,即使你可以,我们也会成为对象切片的牺牲品。
我该怎么办?
似乎我不能使用指针,因为可能有逻辑上相同的Car
s或Truck
s的单独副本(即两个Car
对象分别实例化,但它们代表相同的汽车和operator==
返回true。我需要这些映射到相同的对象在std::map
)
-
您需要使用指向
Vehicle
的指针 -
operator==
不是std::map
使用的,而是std::map
的第三个参数比较函子。默认为std::less
。您需要实现自己的比较函函数来处理Vehicle
:struct less_vehicle: std::binary_function<const Vehicle *, const Vehicle *, bool> { bool operator() (const Vehicle *a, const Vehicle *b) const { ... } };
然后使用它:
std::map<Vehicle *, double, less_vehicle>
您需要使用指针,并传递一个模板实参来指定执行比较的对象类型(当您创建映射时,传递该类型的对象来进行比较)。
对于比较,您需要对指针解引用并比较它们所指向的对象。但是,还要注意,为了成功实现这一点,您需要在Car和Truck之间定义某种比较。它不一定要特别有意义,但它必须是一致的和可传递的(官方术语是它必须定义一个"严格弱排序")。
不能使用ABC作为键,因为拥有ABC的实例没有意义。
对于std::map<Vehicle, double> prices;
行,你说,"用Vehicle
实例作为键制作映射"。因为你不能有Vehicle
的实例(因为它是纯虚拟的),你也不能把它们作为映射的键。
这不是我以前涉足的东西,但我相信使用map
的自定义分配器,您可以使用Vehicle
指针检查逻辑上相同的点。
- 存储在 std::map/std::set 中,与在存储所有数据后对向量进行排序
- 如何在<N>不发生内存泄漏的情况下同时(线程安全)填充 c++11 std::map<std::string,std::bitset*>?
- 无法在 std::map<std::string,std::shared_ptr 中设置值<class>>
- 如何在C++中迭代集合映射(std::map<std::set< char>, int >)?
- 如何初始化结构字段 std::map<std::string, std::string>称为参数
- issue with std::map std::find
- 为什么 std::map< std::map >不释放内存?
- C++ map<std::string> vs map<char *> 性能(我知道,"again?" )
- 确定运行时std::map/std::set的内存使用情况
- 映射上的模板参数无效 std::map< std::string, Stock*> &Stock
- 我的SFINAE检查std::map/std::vector有什么问题
- 使用 std::map<std::string, int> 计算表达式树
- 将数据从两种不同的数据结构插入 std::map <std::string, int> mymap 并通过套接字发送
- 类中的编译器错误,数据类型为 typedef map<std::string,std::p air<std::string,vector<int>>> MapPai
- C++ std::map<std::string, std::set<std::string>> .如何循环设置值?
- 如何填写和访问 std::map<std::p air<enum1, enum2>, funcPtr>?
- 二进制'<':找不到 map<std::string shared_ptr 的运算符<Foo>>
- 如何将 2 个字符* 数组直接映射到 std::map<std::string,std::string>
- C++ std::map<std::string, int> 获取键以特定字符串开头的值
- 从取消引用的迭代器返回 std::map<std::string, int> 时出现巨大的内存泄漏