Как работают итераторные указатели в STL - PullRequest
1 голос
/ 21 апреля 2011

Эй, я немного запутался в том, как работают итераторы.В частности, const_iterator для класса в этом случае.Я понимаю, что они на самом деле являются просто указателями на определенные элементы строки или что-то, с чем вы работаете, но в этом случае: Я бы подумал, что это адрес памяти, поэтому вы не можете просто добавлять целые числачтобы перейти к следующему элементу в строке.

Вот код, в котором я запутался:

string::const_iterator iCharacterLocater;

for ( iCharacterLocater = strSTLString.Begin();
      iCharacterLocater != strSTLString.end();
      ++ iCharacterLocater )
{
    cout << "Character [ " << nCharOffset ++ <<"] is: ";
    cout << *iCharacterLocater << endl;
}

Спасибо!=)

Ответы [ 3 ]

7 голосов
/ 21 апреля 2011

Это немного сложнее, чем это.Итераторы ссылаются на шаблон проектирования GOF с тем же именем и в C ++ применяются таким образом, что они выглядят как указатели.C ++ позволяет перегрузить операторы, что означает, что пользовательские типы могут вести себя особым образом, когда на них используются определенные операторы.

В C ++ имеется несколько типов итераторов с различными уровнями возможностей.Базовое представление вектора и строки достаточно просты, чтобы итераторы вели себя почти так же, как указатели: вы можете добавлять к ним числа для поиска определенного элемента.Например, myVector.begin() + 5 возвращает итератор для 6-го элемента вектора (6-й, потому что индексы начинаются с нуля, а 0 будет первым).Строковые итераторы также позволяют вам делать это.

Строковые константы-итераторы ведут себя подобно константным указателям на символы.Когда вы видите const char* foo, это не значит, что вы не можете изменить foo - это просто означает, что вы не можете изменить то, на что оно указывает.Поэтому, когда вы видите std::string::const_iterator foo, это не значит, что вы не можете изменить foo.Это просто означает, что вы не можете изменить то, на что оно ссылается.

const char* foo = "abcd";
foo = "zyxwvu"; // valid: the pointer itself can be changed
*foo = 't'; // invalid: the pointed data can't be changed
*(foo + 2) == 'x'; // true

std::string myString = "zyxwvu";
std::string::const_iterator foo = myString.begin();
foo = myString.begin() + 2; // valid: the iterator itself can be changed
*foo = 't'; // invalid: the pointed data can't be changed
*(foo + 2) == 'x'; // true

Если вы не пытаетесь изменить данные, итераторы и const итераторы ведут себя одинаково.Кроме того, за исключением того, что между ними нет прямого преобразования, указатель на содержимое строки и итератор на содержимое строки ведут себя одинаково.

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

Это адрес памяти. Особенность этих контейнеров STL заключается в том, что когда вы храните 10 элементов в одном, все эти элементы являются смежными только по этой причине. Так что когда вы itr ++, он указывает на следующий адрес памяти, который гарантированно будет следующим элементом.

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

const std :: string :: iterator означает, что вы не можете изменить итератор. Таким образом, вы не можете увеличить его или указать на что-то другое.

std :: string :: const_iterator означает, что вы не можете изменить значение, на которое указывает итератор. Таким образом, вы можете изменить значение, на которое указывает итератор (itr ++), но вы не можете изменить фактическое значение по этому адресу памяти.

0 голосов
/ 05 июля 2016

Итератор в основном указатель, правильно! Но что действительно важно, это то, на что оно указывает.

Я думаю, что итератор - это указатель на структуру, определенную как type . Например,

  • для вектора типа string, итератор будет указателем на строку структура (строка - это структура, определенная системой)
  • Для вектора типа classA итератор будет указателем на classA структура (в основном класс является определяемой пользователем структурой)

Прелесть определения итератора таким образом заключается в том, что мы можем определить все в форме структуры, поэтому мы можем извлечь все, определив для него итератор.

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