Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;抽象类作为std::map键_C++_Stl_Map_Polymorphism_Abstract Class - Fatal编程技术网

C++ C++;抽象类作为std::map键

C++ C++;抽象类作为std::map键,c++,stl,map,polymorphism,abstract-class,C++,Stl,Map,Polymorphism,Abstract Class,我有这样的类层次结构: struct Vehicle { virtual string model() = 0; // abstract ... } struct Car : public Vehicle {...} struct Truck : public Vehicle {...} 我需要保存一张std::map,其中包含我获取的有关车辆实例的一些信息: std::map<Vehicle, double> prices; std::地图价格; 但是,我得到以下错误

我有这样的类层次结构:

struct Vehicle {
  virtual string model() = 0; // abstract
  ...
}
struct Car : public Vehicle {...}
struct Truck : public Vehicle {...}
我需要保存一张
std::map
,其中包含我获取的有关
车辆
实例的一些信息:

std::map<Vehicle, double> prices;
std::地图价格;
但是,我得到以下错误:

/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()
/usr/include/c++/4.2.1/bits/stl_pair.h:在“std::pair”的实例化中:
/usr/include/c++/4.2.1/bits/stl_-map.h:349:从“_-Tp&std::map::operator[](const_-Key&)[其中_-Key=Vehicle,_-Tp=double,_-Compare=std::less,_-Alloc=std::allocator]”实例化
test.cpp:10:从此处实例化
/usr/include/c++/4.2.1/bits/stl_pair.h:73:错误:无法将字段“std::pair::first”声明为抽象类型“const Vehicle”
型号.hpp:28:注意:因为以下虚拟功能在“const Vehicle”中是纯的:
Model.hpp:32:注意:虚拟字符串Vehicle::Model()
因此,不能将抽象类用作
std::map
键。据我所知,这是因为映射复制它们的键(通过复制构造函数或赋值操作符),这意味着实例化一个抽象类(
Vehicle
)。即使你可以,我们也会成为你的牺牲品

我该怎么办


我似乎无法使用指针,因为可能存在逻辑上相同的
汽车
s或
卡车
s的单独副本。(即,两个分别实例化的
Car
对象,但它们表示相同的Car,
操作符==
返回true。我需要将它们映射到
std::map
中的相同对象)

您需要使用指针,并传递模板参数以指定将执行比较的对象类型(创建地图时,传递该类型的对象以进行比较)


为了进行比较,您需要取消对指针的引用并比较它们所指向的对象。但是,还要注意,为了成功进行比较,您需要在汽车和卡车之间定义某种类型的比较。它不一定特别有意义,但必须是一致的和可传递的(官方术语是它必须定义“严格弱排序”)。

不能将ABC用作键,因为拥有ABC实例没有意义

使用行
std::map prices;
你说的是,“用
Vehicle
实例作为键来制作地图”。因为你不能拥有
Vehicle
的实例(因为它是纯虚拟的),你也不能把它们作为地图的键

这不是我以前涉猎过的东西,但我相信使用带有
map
的自定义分配器,您可以使用
Vehicle
指针来检查逻辑上相同的指针对象

  • 您需要使用指向
    车辆的指针

  • 运算符==
    不是由
    std::map
    使用的,而是一个比较函子,它是
    std::map
    的第三个参数。默认情况下,它是
    std::less
    。您需要实现自己的比较函子才能与
    车辆
    一起工作:

     struct less_vehicle: std::binary_function<const Vehicle *, const Vehicle *, bool>
     {
       bool  operator() (const Vehicle *a, const Vehicle *b) const { ... }
     };
    
    struct less_vehicle:std::binary_函数
    {
    布尔运算符()(常数车辆*a,常数车辆*b)常数{…}
    };
    
  • 然后使用它:

    std::map<Vehicle *, double, less_vehicle>
    
    std::map
    
    为什么不提供
    Vehicle
    a
    price
    会员?或者使用
    map
    将车型名称与价格关联起来?@Beta假设这是用于给定的搜索(例如,在特定的地理区域)。此外,这并不能解决按位复制同步问题;如果您有两个
    汽车
    ,则只有一个实例可以获得价格。真正的汽车通过拥有注册号和唯一的制造序列号来解决此问题。(很抱歉编辑,直到太晚才看到您的评论。)如果一辆
    汽车
    可以有一个以上的价格,这取决于外部的东西,那么我的会员想法就行不通了,但我不认为我理解你的第二点。谢谢Jerry。这意味着我需要区分不同的类别——这是进行RTTI的唯一方法吗?@Adam,你需要某种形式的RTTI,否则这些类别需要相互了解实行双重调度。