【问题标题】:STL list iterator won't update my objectSTL 列表迭代器不会更新我的对象
【发布时间】:2013-12-24 23:09:27
【问题描述】:

我正在使用列表迭代器将 Pets 的所有年龄设置为 1,但更改不会在 for 循环之外持续存在:

#include <iostream>
#include <stdio.h>
#include <list>

using namespace std;

class Pet{
  public:
  int age;
};

class Person{
  public:
  list<Pet> pets;
};


int main(int argc, char **argv) {
  Person bob;
  Pet p1;
  p1.age = 0;
  bob.pets.push_back(p1);

  cout << "Start with: "<<p1.age << endl;

  std::list<Pet>::iterator itPet;
  for (itPet = bob.pets.begin(); itPet != bob.pets.end(); ++itPet) {
    Pet p = (*itPet);
    p.age = 1;
    cout << "Right after setting to 1: "<<p.age << endl;
  }

  cout << "After the for loop: "<<p1.age << endl;
  return 0;
}

输出:

Start with: 0
Right after setting to 1: 1
After the for loop: 0

为什么 p1 没有更新?如果不是 p1,又更新了什么?

谢谢!

【问题讨论】:

    标签: c++ stl iterator


    【解决方案1】:

    你只需修改一个副本:语句

    Pet p = (*itPet);
    

    *itPet 的值复制到p,然后更新。您可以使用以下代码验证迭代器使用的对象:

    p.age = 1;
    cout << "Right after setting to 1: p.age="<<p.age << " itPet->age=" << itPet->age << '\n';
    

    您想给我们一个参考:

    Pet& p = *itPet;
    

    但是,您用来验证列表中的对象是否已更改的方法也不起作用:标准 C++ 库容器会复制插入的对象,并且不会保留对原始对象的引用.也就是说,p1 不会改变,但列表中的元素会改变:

    for (std::list<Pet>::const_iterator it(bob.pets.begin()), end(bob.pets.end());
         it != end; ++it) {
        std::cout << "list after change: " << it->age << '\n';
    }
    

    【讨论】:

    • 如果我使用宠物& p = *itPet;在 for 循环之后,更改仍然不会持续。
    • @ben:确实如此。但是,您正在查看的是您之前制作的副本,当然没有更改!要查看列表中实际更改的值,您需要查看列表。我还将使用标准 C++ 库容器实际上复制原始对象的信息来更新我的答案...
    • 容器之母。非常感谢!
    • 代码风格:难道iteititend 更有意义吗?
    • @Joker_vD:我不这么认为:end 是一个不可移动的位置。是的,理论上它可以移动,但在上面的循环中它肯定不会。当it 打算移动时,它也不会在任何其他单遍遍历中移动。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 2021-08-31
    • 2013-09-23
    • 1970-01-01
    • 2012-11-05
    • 2014-04-26
    相关资源
    最近更新 更多