2014-09-16 3 views
3

Извините за мой английский.Изменить элемент списка

Некоторые класс:

class Kid { 
public: 
    ... 
    string _name; 
    std::list<string> _cuteKids; 
}; 

Использование класса:

std::list<Kid> kids; 
    kids.push_back(new Kid("Jeck")); 
    kids.push_back(new Kid("Anna")); 
    kids.push_back(new Kid("Toma")); 

    for(auto e: kids) { 

     e._cuteKids.push_back("Jeck"); // Many some names... 
     [1] 
    } 
    [2] 

Если вы посмотрите на код в отладчике, список в пункте 1 _cuteKids - есть предмет. Но если посмотреть на список в параграфе 2 _cuteKids - нет предмета. Зачем?

Это всего лишь пример, на самом деле я очень усложнил алгоритм, но нижняя строка заключается в том, что после цикла _cuteKids становится пустым. Как будто это статическая переменная (e: дети), а не указатель на переменную дети.

+0

Почему «Малыш» содержит список «милых детей»? Ребенок - это ребенок. Один ребенок не содержит других детей. Это не имеет смысла. У вас также есть проблема с уровнями косвенности. Учитывая 'std :: list kids;', 'kids.push_back (new kid (" xxx ");' не может компилировать - 'new' дает указатель, но вы пытаетесь вставить этот указатель в качестве объекта для который он ссылается. –

+0

Странно, что у вас есть 'std :: list kids;', а затем вы добавляете новый 'kid' using ** 'new' **:' kids.push_back (новый Kid («Jeck»)) ; '... –

+0

_cuteKids - это список детей, которые любят ребенка. Работа, он не меняет. –

ответ

1

В коде:

for (auto e: kids) { 
    e._cuteKids.push_back("Jeck"); // Many some names... 
} 

вы делаете копии каждого элемента в kids контейнере , в то время как итерация самого контейнера, потому что вы пропустили «простой»&.

Таким образом, оператор e._cuteKids.push_back(...); работает на копии, не на исходной позиции. Эта местная копия «испаряется» после каждой итерации цикла, а исходные элементы в контейнере kids: не затрагивается.

Вы должны правильно перебирать с помощью ссылки (&) к исходным пунктам, чтобы избежать этих локальных глубокие копии:

for (auto& e : kids) { 
    // ... do something on 'e' ... 
} 

Обратите внимание, что есть предложение на основе диапазона немногословный for Петли (N3994), которые могут быть частью следующей итерации языка (C++ 17?), Чтобы избежать ошибок, как те, в вашем коде:

Range-Based For-Loops: The Next Generation (Revision 1)

Используя этот недавно предложенный синтаксис, может быть можно просто написать:

for (e : kids) { 
    // ... do something on 'e' ... 
} 

без введения тонких ошибок как забывая &.

4

e - это копия элементов списка, поэтому изменения в ней не влияют на элементы в списке.

Чтобы сделать то, что вы хотите, сделать e ссылку:

for (auto &e : kids) 
+0

Действительно благодарю вас! Я люблю C++ 11.: '( –

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