Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > foreach Qt4 баг?


Автор: zaytsewa 24.3.2011, 15:52
Всем привет!

Вчера заметила следующее:

есть
QVector<GLTriangle> triangles;

изначально конструктора по умолчанию у GLTriangle не было, но тогда компилятор ругался что не может поместить объекты типа GLTriangle в QVector
после этого я добавила пустой конструктор и метод setCoords(MnGis::GeoVector& v) с параметром, который должен быть в конструкторе 
[
Код

  for (int i = 0; i < vn.count();++i)
  {
   GLTriangle triangle(vn[i]);
   triangles.append(triangle); 
   triangles[i].setCoords(vn[i]);
  }


далее я инициализирую данные в объекте класса GLTriangle
Код

  GLTriangle triangle;
   foreach(GLTriangle triangle,triangles)
 {
     triangle.initBuffers();
   }



а тут я хотела получить объекты с заполненными данными, не тут-то было! Все объекты оказались без инициализированных данных....

Код

   GLTriangle triangle;
   foreach(GLTriangle triangle,triangles)
   {
     triangle.draw(program);
   }


использую по-старинке и всё работает

Код

   for (int i = 0; i < triangles.count();++i)
   {
     triangles[i].initBuffers();
  }


кто-нибудь объясните мне, почему так?

Автор: borisbn 24.3.2011, 15:56
Цитата(zaytsewa @  24.3.2011,  15:52 Найти цитируемый пост)

foreach(GLTriangle triangle,triangles)
{
    triangle.initBuffers();
}

Qt-шный foreach работает с копией объекта (или константной ссылкой).
изменять объекты при помощи Qt-шного foreach нельзя. 

Автор: bsa 24.3.2011, 16:10
Странный код:
Код
  for (int i = 0; i < vn.count();++i)
  {
   GLTriangle triangle(vn[i]);
   triangles.append(triangle); 
   triangles[i].setCoords(vn[i]);
  }
Зачем координаты два раза задаются? И почему нельзя использовать тут foreach:
Код
foreach(const Type &v, vn)
   triangles.append(GLTriangle(v));

Автор: zaytsewa 24.3.2011, 16:10
там дважды задаётся параметр, тк я сначала грешила на конструктор

Код

foreach(const Type &v, vn)
   triangles.append(GLTriangle(v));
    

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

Автор: _GRIN_ 25.3.2011, 16:13
"Qt automatically takes a copy of the container when it enters a foreach loop. If you modify the container as you are iterating, that won't affect the loop. (If you do not modify the container, the copy still takes place, but thanks to implicit sharing copying a container is very fast.)
Since foreach creates a copy of the container, using a non-const reference for the variable does not allow you to modify the original container. It only affects the copy, which is probably not what you want."

Т.е. в foreach - проход осуществляется по копии контейнера, и внутри foreach нельзя изменить содержимое оригинального контейнера!!!
При необходимости менять содержимое контейнера лучше использовать итераторы - это и работает быстрее =)

Автор: bsa 25.3.2011, 18:47
Цитата(zaytsewa @  24.3.2011,  16:10 Найти цитируемый пост)
у меня так не получилось, типа тут должен вызываться конструктор без параметра

Если ты вместо Type укажешь тип элементов контейнера vn, то все должно работать. Иначе, твой код тоже не скомпилировался бы.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)