为什么我的键被覆盖时,插入一个对象到映射

Why are my keys being overwritten when inserting an object into a map?

本文关键字:插入 一个对象 映射 我的 覆盖 为什么      更新时间:2023-10-16

我遇到了这样一个问题:在向映射中插入元素时,我假设每次向其中放入新对象时,前一个对象都会被覆盖。每当我去打印地图的内容时,只打印最近添加的项目。我有两个类,一个是Recipe类,一个是Ingredient类。我的食谱有一个map<Ingredient*, int>,它包含一个对象和它的数量。

Recipe::Recipe(){
    title = "";
    ingredients;
}
void Recipe::insertIngredient(Ingredient* item, int quantity){
    ingredients.insert( make_pair( item, quantity  ) );
}
Ingredient::Ingredient(){
    name = "";
    unit = "";
}

对于用于初始化变量和打印内容的每个类,我都有getter和setter,但是每当我打印Recipe的映射的内容时,只打印我放入其中的最后一项。下面是我在主函数中打印地图的代码。

map<Ingredient*, int> tempIngredients = tempRecipe->getIngredients();
map<Ingredient*, int>::iterator ingredientIt;
for (ingredientIt = tempIngredients.begin(); ingredientIt!= tempIngredients.end();    ingredientIt++) {
    Ingredient* tempIngredient  = ingredientIt->first;
    int quantity = ingredientIt->second;
    cout << "n" << tempIngredient->getName() << " " << tempIngredient->getUnit() << " " <<  quantity << flush;
}

目前我的输出如下:

未漂白小麦混合粉C. 1

是我添加的最后一个元素的成分名称、单位和数量(来自映射的值)。

使用指针作为映射键,而没有实现比较操作符。

您最好使用Ingredient对象并实现operator<

例如,

class Ingredient {
    public:
        bool operator<(const Ingredient & b) const {
            return getName() < b.getName();
        }
    // Rest of class methods data etc...
};
std::map<Ingredient, int> ingredients;

你怎么呼叫insertIngredient ?由于您的映射是由Ingredient*键控制的,因此每个条目必须是唯一的Ingredient对象(通过新建或离开堆栈),否则键将冲突。

真正的问题是你为什么要在指针上按键?根据@GWW的回答,一个更好的解决方案是存储Ingredient值并为它们创建一个自定义比较器函数。