【问题标题】:Why doesn't list update after erasing element inside function?为什么删除函数内的元素后列表不更新?
【发布时间】:2020-05-11 19:18:04
【问题描述】:

我目前正在做一个项目,并且花了太多时间试图解决这个问题

ItemOrdered.h:

public:
    Item* getItem();
private:
    Item* item;
    int quantity;

ItemOrdered.cpp:

Item* ItemOrdered::getItem(){return item;}

ShoppingCart.h:

public:
    void addItemOrdered(Item* orderedItem, int quantity);
    void removeItemOrdered(Item* orderedItem);

private:
    list<ItemOrdered> orderList;

ShoppingCart.cpp:

void ShoppingCart::addItemOrdered(Item* orderedItem, int quantity){

    updateItemStock(orderedItem, quantity);
    ItemOrdered oitem(orderedItem, quantity);
    orderList.push_back(oitem);//This gets updated
}        


void ShoppingCart::removeItemOrdered(Item* orderedItem){

    list<ItemOrdered> :: iterator z;

    for(z = orderList.begin(); z != orderList.end(); ++z){

        if(z->getItem()->getID() == orderedItem->getID()){
            orderList.erase(z);//This does not get updated
        }
    }
}

ma​​in.cpp:

buyer1.getCart().showCart();//This shows the items ordered in the cart
buyer1.getCart().removeItemOrdered(pap2Pointer);//Remove this item from the *orderList*
buyer1.getCart().showCart();//Shows the same items, *orderList* was not updated 

我无法理解这一点。主要原因是我对将项目添加到 orderList 的功能没有任何问题。它已正常更新。我尝试对 removeItemOrdered() 函数内的 orderList 进行任何类型的更改,但无济于事。 我无法理解我的两个函数之间的区别以及为什么一个更新它而另一个不更新。

编辑:这是showCart()函数:

void ShoppingCart::showCart(){

    list<ItemOrdered> :: iterator i;
    int j=1;
    for(i=orderList.begin(); i!=orderList.end(); ++i){
        cout<<j<<". "<<i->getItem()->getName()<<" ("<<i->getQuantity()<<")"<<endl;
        j++;
    }
}

【问题讨论】:

  • 您是否使用调试器逐步执行该函数以确保找到对象?
  • 似乎很明显需要调查,您的 if 声明永远不会正确。为什么?因为你在其他地方有错误。
  • 我会检查 @user4581301 所说的内容并确保您确实找到了该元素,但我也将退出 for 循环,或者至少将其更改为 z=orderList.erase(z); 这将删除项目后更新迭代器。
  • 正在使用的列表是否为std::list?如果是这样,为什么不同时使用std::find()?这个函数大概是三行左右。
  • @AndreasKostas 我们不知道何时、何地或如何调用这些函数。此外,您正在使用指针,我们也不知道这些指针在何处、何时以及如何初始化。我们需要看到minimal reproducible example。但无论如何,您需要先修复您的代码,正如我在继续之前给出的答案中所指出的那样。您的纠删码目前无效。

标签: c++ list


【解决方案1】:

您的代码从std::list 中删除有一个问题,即如果项目被删除,您将访问无效的迭代器。

void ShoppingCart::removeItemOrdered(Item* orderedItem){
    list<ItemOrdered> :: iterator z;
    for(z = orderList.begin(); z != orderList.end(); ++z){
        if(z->getItem()->getID() == orderedItem->getID()){
            orderList.erase(z); // <-- z is now invalidated
        }
    }
}

问题是如果发生擦除,z 将失效,因此当循环执行++z 时,将被递增的z 不再有效。

编写循环的正确方法是在发生擦除时重新分配迭代器,如here 所述:

void ShoppingCart::removeItemOrdered(Item* orderedItem){
    list<ItemOrdered> :: iterator z;
    for(z = orderList.begin(); z != orderList.end(); ){
        if(z->getItem()->getID() == orderedItem->getID()){
            z = orderList.erase(z); // <-- z is now assigned to the next item
        }
        else
          ++z;
    }
}

【讨论】:

  • 不幸的是,情况并非如此。无论我对orderList 进行什么更改,它都不会更新。尽管removeItemOrdered() 内部确实发生了变化,但似乎showCart() 并没有加载新的orderList。就像我对orderList 所做的任何更改最终都会卡在函数中
  • 好吧,你的代码是错误的。你很幸运,你没有发生崩溃。答案指出了代码中的一个明显错误,您必须在考虑其他任何事情之前修复它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多