2013-12-24 3 views
2

Я использую список итератор, чтобы установить все возрасты домашних животных 1, но изменения не будут сохраняться вне цикла:STL список итератор не обновляет объект

#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?

Спасибо!

ответ

8

Вы просто изменить копию: заявление

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'; 
} 
+0

Если я использую Pet & р = * itPet; изменение по-прежнему не сохраняется после цикла for. – ben

+0

@ben: делает. Однако вы смотрите на копию, которую вы сделали ранее, которая, конечно же, не изменилась! Чтобы увидеть, что значение действительно изменилось в списке, вам нужно посмотреть список. Я также обновлю свой ответ информацией о том, что стандартные контейнеры библиотеки C++ фактически делают копию исходного объекта ... –

+0

Мать контейнеров. Спасибо огромное! – ben

Смежные вопросы