В векторе / списке вы действительно применяете его к объекту? (C ++) - PullRequest
2 голосов
/ 26 апреля 2011

Допустим, у меня есть вектор:

vector<Block> myBlocks;

И скажем, я делаю это:

Block b(10); //Let's assume this will set b's variable: x to 10
myBlocks.push_back(b); //Add it to the vector/list

Теперь, что, если где-то еще я сделал это:

for(int i = 0; i<myBlocks.size(); i++){
    Block c = myBlocks.at(i);
    c.x = 15; //Will this work?
}

Куда я положил: c.x = 15;, действительно ли это устанавливает позицию x этого блока в 15? Или это только установка позиции x 1011 * временного блока в 15? Если это только установка временного блока, как мне установить его для фактического блока?

Ответы [ 5 ]

6 голосов
/ 26 апреля 2011
Block c = myBlocks.at(i);

Здесь c - это копия значения, содержащегося в myBlocks.

Block& c = myBlocks.at(i);

Здесь c - это ссылка на (т. Е. псевдоним of) значение, содержащееся в myBlocks.

Я подозреваю, что вы хотите последнее.

2 голосов
/ 26 апреля 2011

Куда я положил: "c.x = 15", действительно ли это установка позиции x этого блока в 15?

номер

Или это только установка позиции x временного блока в 15?

Да.

Если это только установка временного блока, как мне установить его для фактического блока?

myBlocks.at(i).x = 15 ; // Assuming x has a public access.

Block c = myBlocks.at(i);

myBlocks.at(i) возвращает объект, скопированный в c. Таким образом, объекты (объект в векторе, c) - это два разных объекта со своими собственными членами (при условии, что у класса нет необработанных указателей).

1 голос
/ 26 апреля 2011

C ++ - это язык, основанный на copy семантическом , поэтому, когда вы делаете что-то вроде

Block c = myblocks.at(i);

Вы действительно делаете копию объекта блока. Обратите внимание, что в C ++ жаргон не называется «временным» ... временные выражения в C ++ - это очень специфический термин, означающий неназванные объекты, созданные автоматически и не объявленные.

Это поведение копирования весьма отличается от многих других языков, таких как Python или Java, где вместо этого используется эталонная семантика .

Вы можете попросить не делать копию явно, используя "ссылку" ...

Block& c = myblocks.at(i);

и в этом случае при изменении c вы работаете с исходным элементом внутри вектора. Обратите внимание, что в этом случае вы должны обратить внимание на то, как долго вы сохраняете свою ссылку, потому что, например, если вы добавляете элемент к вектору, все существующие ссылки и итераторы потенциально становятся недействительными из-за перераспределения векторов, и их использование вызовет ужасную неопределенность. Поведенческий демон.

Если ссылка или итератор признаны недействительными или нет, зависит от типа контейнера, от типа операции, которую вы выполняете над контейнером, и от других фактов, таких как резервирование пространства, поэтому я предлагаю прочитать хорошую книгу по C ++, чтобы понять эти части .

Обратите внимание, что и std::vector::operator [], и std::vector::at фактически возвращают ссылку, чтобы ваш код мог также изменить исходный объект в векторе, используя более лаконичный и идиоматический синтаксис

myblocks.at(i).x = 15;
1 голос
/ 26 апреля 2011

Что вы работаете с копией исходного элемента.

Я бы посоветовал вам использовать idiomatic iterator как:

for(std:vector<Block>::iterator it=myBlocks.begin(); it!=myBlocks.end(); it++)
{
    it->x = 15 ;// this will work - will update the actual element, not its copy!
    (*it).x = 15 ;// this will also work
}
1 голос
/ 26 апреля 2011

Это будет работать:

  Block& c = myBlocks.at(i); // note reference here
  c.x = 15; //Will this work?

Ваша тоже будет работать, но в конце ничего не будет делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...