2012-02-04 3 views
1

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

Object* object; 

object = vectorOfObjects.end(); 

или

object = &vectorOfObjects.end(); 

или

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

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

+0

Я предполагаю, что вы не хотели объявлять объект как указатель после того, как явным образом сказал, что ваши объекты были по значению? – David

ответ

11

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

object = vectorOfObjects.end(); 

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

object = &vectorOfObjects.end(); 

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

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

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

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

+0

Очень краткий ответ. – kmiklas

2

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

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

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

std::vector<Object> vec; 
std::vector<Object>::iterator it; 
//.... 
it = vec.begin(); 
Object o = *it; 
+1

if (it! = Vec.end() {o = * it;} –

2

Это происходит потому, что в соответствии с соглашением 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

Даже если вы используете .begin, это не сработает, настоящая причина в том, что он возвращает итератор, который является другим типом объекта –

+0

@lzprgmr Вот почему я добавил звездочку, чтобы на самом деле * разыменовать * итератор, например, заголовок вопроса говорит :) – dasblinkenlight

+0

Старт() опечатка для begin()? –

-1

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

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