почему я не могу разыменовать итератор? - PullRequest
1 голос
/ 04 февраля 2012

Если у меня есть вектор объектов (простые объекты, а не указатели или ссылки), почему я не могу сделать это?*

object = &(*vectorOfObjects.end());

также тот же вопрос, если «объект» был ссылкой.

Ответы [ 4 ]

12 голосов
/ 04 февраля 2012

Это три отдельные ошибки:

object = vectorOfObjects.end();

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

object = &vectorOfObjects.end();

не работает, потому что вы берете адрес возвращенного итератора. То есть вы получаете указатель на итератор, а не указатель на Object.

object = &(*vectorOfObjects.end());

не работает, потому что итератор end не указывает на допустимый элемент. Он указывает один за концом последовательности. И так, это не может быть разыменовано. Вы можете разыменовать последний элемент в последовательности (который будет --vectorOfObjects.end()), но не итератор, указывающий за конец.

Наконец, основная проблема / путаница может заключаться в том, что вы думаете, что итератор может быть преобразован в указатель. В общем, не может. Если ваш контейнер является вектором, вы гарантированно размещаете элементы непрерывно, как в массиве, и, таким образом, указатель будет работать. Но, скажем, для list указатель на элемент бесполезен. Это не даст вам никакого способа добраться до следующего элемента next .

3 голосов
/ 04 февраля 2012

Поскольку .end() возвращает итератор, а не Object, который даже не является допустимым членом вектора.

Даже используя begin(), который возвращает действительный объект, вынужно следующее:

Правильный путь будет:

std::vector<Object> vec;
std::vector<Object>::iterator it;
//....
it = vec.begin();
Object o = *it;
2 голосов
/ 04 февраля 2012

Это связано с тем, что по соглашению end не указывает на допустимое местоположение в контейнере: оно находится в местоположении за концом контейнера, поэтому разыменование его недопустимо.

Ситуация с begin() отличается: вы можете разыменовать ее, когда v.begin() != v.end() (т. Е. Когда контейнер не пустой):

object = *vectorOfObjects.begin();

Если вам нужен доступ к последнему элементу, вы можете сделать это:

vector<object>::const_iterator i = vectorOfObjects.end();
i--;
cout << *i << endl; // Prints the last element of the container

Опять же, это работает, только если ваш вектор содержит хотя бы один элемент.

0 голосов
/ 04 февраля 2012

Объект * означает указатель на Объект, где указатель является адресом памяти.Но метод .end () возвращает Iterator, который является самим объектом, а не адресом памяти.

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