Страницы

Поиск по вопросам

пятница, 14 декабря 2018 г.

Использование итераторов С++ с массивами

Возможно, кто-либо может объяснить итераторы и их использование с массивами, или же дать соответствующую литературу по этой теме?
Т.к. я читал по разным книгам о итераторах, но там идет речь о использовании их совместно с STL и т.п., а как самому написать - особо такого не написано... Насколько я понял, то они нужны, чтобы перебирать и т.п. элементы массива. Я правда не знаю смысл в этом, если вроде бы можно и непосредственно обращаться, ну да ладно, не важно. Т.е. нужно создать вложенный класс внутри класса, где будет содержаться, скажем, массив?
Если я понял, то в конце концов, когда он написан, то, к примеру, для цикла выведения массива будет такой код:
for(start = Iterator.begin(); start != end; start++) { cout << *start; }
Или я что-то путаю?
P.S.: А ещё, если у кого есть книги, где об этом говорится, статьи, то пожалуйста и их напишите тоже сюда.

class Array { private: int* p; public: class Iterator { public: Iterator() { p = nullptr; } Iterator(int *pv) { p = pv; } int operator *() const { return *p; } Iterator operator ++(int) { int *temp = p; return ++temp; } };
Array(); ~Array(); int& operator[] (); Iterator begin() { return Iterator(buffer_) } int* buffer_;
void partial_sort(Array::Iterator start, Iterator end) { start }
Вот как понять что-то вроде этого... Точнее говоря это наброски, они не совсем мои.. Вот мне нужно сделать примерно такое же, только работающее..

Если говорить поконкретнее насчёт того, что не понимаю... Вот класс итератор вложенный, в нем какое поле должно быть ? При перегрузке Iterator operator ++(int) это он типо должен будет перебирать элементы массива же, да? А если я хочу перегрузить ==? Я пробовал писать что-то вроде:
Iterator operator==(Iterator it1, Iterator it2)
Чтобы сравнивать их на равенство, но не получается - ошибка "много аргументов". ДА и ещё не до конца понимаю как его реализовать.. Т.е. допустим функции вывода, сортировок вместо того, чтобы передавать массив и его длину мне нужно будет передавать 2 итератора, верно? Один из них указывает на начало, другой на конец, да? А вывод массива в таком случае выглядел бы с итераторами так:
for(start ???; start != end; start++) cout << *start;


Ответ

Вот, собственно, пример итератора. Этот код вырезан из SGI STL, почищен от всяких подробностей, чтобы оставить суть. Тут можно посмотреть что и как в итераторах должно быть в принципе: #include // нужен только лишь для типа std::size_t
class iterator { protected: int* p;
public: explicit iterator(int* __i) : p(__i) { }
// Forward iterator requirements const int& operator*() const { return *p; }
int& operator*() { return *p; }
int* operator->() const { return p; }
// prefix increment (++it) iterator& operator++() { ++p; return *this; }
// postfix increment (it++) iterator operator++(int) { return iterator(p++); }
// Bidirectional iterator requirements
// prefix decrement (--it) iterator& operator--() { --p; return *this; }
// postfix decrement (it--) iterator operator--(int) { return iterator(p--); }
// Random access iterator requirements const int& operator[](const std::size_t& __n) const { return p[__n]; }
int& operator[](const std::size_t& __n) { return p[__n]; }
iterator& operator+=(const std::size_t& __n) { p += __n; return *this; }
iterator operator+(const std::size_t& __n) const { return iterator(p + __n); }
iterator& operator-=(const std::size_t& __n) { p -= __n; return *this; }
iterator operator-(const std::size_t& __n) const { return iterator(p - __n); }
int* base() const { return p; } };
// Forward iterator requirements inline bool operator==(const iterator& __lhs, const iterator& __rhs) { return __lhs.base() == __rhs.base(); }
inline bool operator!=(const iterator& __lhs, const iterator& __rhs) { return __lhs.base() != __rhs.base(); }
// Random access iterator requirements inline bool operator<(const iterator& __lhs, const iterator& __rhs) { return __lhs.base() < __rhs.base(); }
inline bool operator>(const iterator& __lhs, const iterator& __rhs) { return __lhs.base() > __rhs.base(); }
inline bool operator<=(const iterator& __lhs, const iterator& __rhs) { return __lhs.base() <= __rhs.base(); }
inline bool operator>=(const iterator& __lhs, const iterator& __rhs) { return __lhs.base() >= __rhs.base(); }
inline std::size_t operator-(const iterator& __lhs, const iterator& __rhs) { return __lhs.base() - __rhs.base(); }
inline iterator operator+( std::size_t __n, const iterator& __i) { return iterator(__i.base() + __n); } Обратите внимание на explicit конструктор, на то какие операторы перегружены для того, чтобы итератор удовлетворял концепциям: forward iterator random access iterator bidirectional iterator

Комментариев нет:

Отправить комментарий