Форум программистов, компьютерный форум CyberForum.ru

Как реализуется типичный итератор? - C++

Восстановить пароль Регистрация
 
Buckstabue
 Аватар для Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
30.10.2013, 03:16     Как реализуется типичный итератор? #1
Хочется для своего списка написать класс-итератор. Вопрос: от какого класса лучше всего наследоваться, как лучше всего организовать архитектуру и т.п.
Если есть живой пример, то буду глубоко благодарен за такой подарок
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Shtirliz72
200 / 160 / 38
Регистрация: 25.10.2013
Сообщений: 527
30.10.2013, 03:25     Как реализуется типичный итератор? #2
Не пробовал разобрать и рассмотреть std::iterator?
Buckstabue
 Аватар для Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
30.10.2013, 03:30  [ТС]     Как реализуется типичный итератор? #3
Shtirliz72, пробовал, но просто может быть, это не самый образцовый пример и в нормальных приложениях делается он совсем по-другому, а я люблю, когда все не просто работает, но еще и красиво реализовано
Shtirliz72
200 / 160 / 38
Регистрация: 25.10.2013
Сообщений: 527
30.10.2013, 04:08     Как реализуется типичный итератор? #4
Цитата Сообщение от Buckstabue Посмотреть сообщение
Shtirliz72, пробовал, но просто может быть, это не самый образцовый пример и в нормальных приложениях делается он совсем по-другому, а я люблю, когда все не просто работает, но еще и красиво реализовано
Ну, честно, после таких слов я даже и не знаю. Если iterator стандарта с++ - не образцовый пример, тогда что - образцовый?
Вот ещё реализация qiterator, но она ещё более запутана.

Добавлено через 6 минут
Вот ещё маленькая заметка на английском.
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4922 / 2665 / 243
Регистрация: 29.11.2010
Сообщений: 7,420
30.10.2013, 04:31     Как реализуется типичный итератор? #5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#ifndef _MYITERATOR_H_
#define _MYITERATOR_H_
#include <iterator>
 
template <typename T>
class MyIterator
{
public:
    typedef T value_type;
    typedef T* pointer;
    typedef T& reference;
    typedef std::forward_iterator_tag iterator_category;
    typedef ptrdiff_t difference_type;
 
    // конструкторы
    MyIterator();
    MyIterator(T *);
    MyIterator(const MyIterator &);
    // оператор присваиваний
    MyIterator& operator =(const MyIterator &);
 
    // сдвиги операторов
    MyIterator& operator ++();    // префиксный инкремент
    MyIterator  operator ++(int); // постфиксная инкремент
 
    // операторы обращения
    T& operator *();
    T* operator ->();
 
    // операторы сравнения
    bool operator ==(const MyIterator &);
    bool operator !=(const MyIterator &);
 
private:
    T* current;
};
 
 
template <typename T>
MyIterator<T>::MyIterator() : current(0)
{}
 
template <typename T>
MyIterator<T>::MyIterator(T* curr) : current(curr)
{}
 
template <typename T>
MyIterator<T>::MyIterator(const MyIterator& other) : current(other.current)
{}
 
template <typename T>
MyIterator<T>& MyIterator<T>::operator =(const MyIterator& other)
{
    // исключаем присваивание самому себе
    if (this != &other)
        current = other.current;
 
    return *this;
}
 
//префиксная версия возвращает значение после инкремента
template <typename T>
MyIterator<T>& MyIterator<T>::operator ++()
{
    ++current;
    return *this;
}
 
//постфиксная версия возвращает значение до инкремента
template <typename T>
MyIterator<T> MyIterator<T>::operator ++(int)
{
    MyIterator tmp(*this);
    operator++();
    return tmp;
}
 
template <typename T>
T& MyIterator<T>::operator *()
{
    return *current;
}
 
template <typename T>
T* MyIterator<T>::operator ->()
{
    return current;
}
 
template <typename T>
bool MyIterator<T>::operator ==(const MyIterator &other)
{
    return current == other.current;
}
 
template <typename T>
bool MyIterator<T>::operator !=(const MyIterator &other)
{
    return !(*this == other);
}
 
#endif
Buckstabue
 Аватар для Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
30.10.2013, 16:07  [ТС]     Как реализуется типичный итератор? #6
Спасибо, а как лучше всего реализовывать итератор на конец? Он будет просто хранить нулевой указатель?

Добавлено через 49 минут
Вот интерфейс класса. Вопрос: куда пихать класс итератора?
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
template <class T>
struct ListNode
{
    T data;
    ListNode<T> *next;
};
 
template <class T>
class List
{
public:
    List();
    List(const List<T>& x);
    bool push_front(const T& x);
    bool push_back(const T& x);
    bool empty() const { return list_size == 0; }
    uint size() const {return list_size; }
    T front() const { return first->data; }
    T back() const { return last->data; }
    void pop_front();
    void pop_back();
    void clear();
    void sort();
    bool remove(const T& value);
    bool remove(const ListNode<T> * const node);
    void splice(List<T>& listOther);
    virtual ~List();
    List<T>& operator=(const List<T>& x);
    ListNode<T> * getFirst() { return first; }
    ListNode<T> * getLast() { return last; }
    void setFirst(ListNode<T> *x) { first = x; }
    void setLast(ListNode<T> *x) { last = x; }
    std::ofstream& operator<<(std::ofstream& out);
 
private:
    ListNode<T> *first;
    ListNode<T> *last;
    uint list_size;
};


Добавлено через 37 минут
Всем спасибо, оказывается ничего сложного. Решил объвить вложенный класс и все работает.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
template <class T>
struct ListNode
{
    T data;
    ListNode<T> *next;
};
 
template <class T>
class List
{
public:
    List();
    List(const List<T>& x);
    bool push_front(const T& x);
    bool push_back(const T& x);
    bool empty() const { return list_size == 0; }
    uint size() const {return list_size; }
    T front() const { return first->data; }
    T back() const { return last->data; }
    void pop_front();
    void pop_back();
    void clear();
    void sort();
    bool remove(const T& value);
    bool remove(const ListNode<T> * const node);
    void splice(List<T>& listOther);
    virtual ~List();
    List<T>& operator=(const List<T>& x);
    ListNode<T> * getFirst() { return first; }
    ListNode<T> * getLast() { return last; }
    void setFirst(ListNode<T> *x) { first = x; }
    void setLast(ListNode<T> *x) { last = x; }
    std::ofstream& operator<<(std::ofstream& out);
 
    class iterator : public std::iterator<std::forward_iterator_tag, T>
    {
    public:
        iterator() : curNode(NULL){ }
        iterator(ListNode<T> * node) : curNode(node) { }
        iterator(const iterator& other) : curNode(other.curNode) { }
        iterator& operator++() { curNode = curNode->next; }
        iterator operator++(int) { iterator tmp(*this); operator ++(); return tmp; }
        T& operator*(){ return curNode->data; }
        T* operator->() { return &(curNode->data); }
        iterator& operator=(const iterator& rhs)
        {
            if (this != &rhs)
            {
                curNode = rhs.curNode;
            }
 
            return *this;
        }
 
        bool operator==(const iterator& rhs) { return curNode == rhs.curNode; }
        bool operator!=(const iterator& rhs) { return curNode != rhs.curNode; }
    private:
        ListNode<T> *curNode;
    };
 
    iterator begin() { return iterator(first); }
    iterator end()   { return iterator(); }
 
private:
    ListNode<T> *first;
    ListNode<T> *last;
    uint list_size;
};
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.10.2013, 16:29     Как реализуется типичный итератор?
Еще ссылки по теме:

C++ Как закончить ввод в итератор ввода для потока
C++ как создать копию объекта, на который ссылается итератор?
Типичный цикл или сложение чисел C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
30.10.2013, 16:29     Как реализуется типичный итератор? #7
Buckstabue, Вложенный класс не обязательное условие. Просто в классе, который использует итератор должен быть typedef.

Добавлено через 8 минут
Хотя на самом деле, если не хочется много писать можно поюзать boost::iterator_adaptor/boost::iterator_facade
http://www.boost.org/doc/libs/1_54_0...de-and-adaptor

Добавлено через 11 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template<typename T>
class list_iterator : public boost::iterator_facade
<
   list_iterator<T>, ListNode<T>, boost::forward_traversal_tag
>
{
public:
   list_iterator() : cur_node(0) {}
   list_iterator(ListNode<T>* node) : cur_node(node) {}
private:
   friend class boost::iterator_core_access;
   void increment()
   {
       cur_node = cur_node->Next;
   }
   bool equal(const list_iterator& rhs) const
   {
       return cur_node == rhs.cur_node;
   }
   ListNode<T>& dereference() const
   {
       return *cur_node;
   }
   
   ListNode<T>* cur_node;       
};
Yandex
Объявления
30.10.2013, 16:29     Как реализуется типичный итератор?
Ответ Создать тему
Опции темы

Текущее время: 20:40. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru