簡體   English   中英

C ++抽象類作為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 )。 即使你可以,我們也會成為對象切片的犧牲品。

我該怎么辦?

似乎我不能使用指針,因為可能存在邏輯上相同的CarTruck的單獨副本。 (即兩個Car對象分別實例化,但代表相同的car和operator==返回true。我需要這些對象映射到std::map的同一個對象。)

  1. 您需要使用指向Vehicle指針。

  2. 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>

您需要使用指針,並傳遞模板參數以指定將執行比較的對象類型(當您創建地圖時,傳遞該類型的對象以進行比較)。

為了進行比較,您需要取消引用指針並比較它們指向的對象。 但是請注意,為了成功,您需要在汽車和卡車之間定義某種比較。 它不一定非常有意義,但它必須是一致的和可傳遞的(官方術語是它必須定義“嚴格的弱排序”)。

你不能使用ABC作為關鍵,因為擁有ABC的實例是沒有意義的。

使用行std::map<Vehicle, double> prices; 你說,“制作一個以Vehicle 實例為關鍵字的地圖”。 由於您不能擁有Vehicle實例(因為它是純虛擬的),因此您不能將它們作為地圖的鍵。

這不是我以前討論過的東西,但我相信使用自定義分配器和map你可以使用Vehicle指針檢查邏輯上相同的指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM