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

Checked_iter - C++

Восстановить пароль Регистрация
 
 
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
25.07.2013, 04:13     Checked_iter #1
Здорова господа!
Я тут пытаюсь создать свой Checked_iter, вот код который из книги набрал вроде кое-как работает:
Кликните здесь для просмотра всего текста
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//Chacked_iter
#include <iostream>
using std::cout;
using std::endl;
using std::cerr;
#include <list>
using std::list;
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <iterator>
using std::iterator_traits;
 
struct out_of_bounds{};
 
template<class Cont,class Iter=typename Cont::iterator>
class Checked_iter : public iterator_traits<Iter>//наследует все типы итераторов
{
public:
    Iter curr;//итератор для текущей позиции
    Cont* c;//указатель на текущий элемент
    //...
 
    void valid(Iter p)const
    {
        if(c->end()==p)return;//если конец, то возврат
        for(Iter pp=c->begin();pp!=c->end();++pp) if(pp==p)return;//если pp=p, то елемент найден возврат
        throw out_of_bounds();//элемент не находится в последовательности выход
    }
 
    //оператор сравнения
    friend bool operator==(const Checked_iter& i,const Checked_iter& j)
    {
        return i.c==j.c&&i.curr==j.curr;
    }
 
    //нет умолчательного инициализатора (конструктора по умолчанию)
    //конструктор предобразования
    Checked_iter(Cont& x, Iter p) :c(&x),curr(p){valid(p);}
    //конструктор копирования
    Checked_iter(Cont& x) :c(&x),curr(x.begin()){}
 
    //операция разыменования
    reference operator*()const
    {
        if(curr==c->end())throw out_of_bounds();//еси текущий элемент равен консу, то генерация выхода за границы
        return *curr;//если не равен, то возврат значения по ссылке
    }
 
    //доступ через указатель
    pointer operator->() const
    {
        if(curr==c->end())throw out_of_bounds();//если текущий элемент равен концу, то генерация выхода за границы
        return &*curr;//возврат указателя на элемент
    }
 
    //операция '+'
    Checked_iter operator+(difference_type d)const//только для итераторов произвольного доступа
    {
        //тут похоже какието действия с указателями
        //если указатель на конец минус текущий указатель меньше d
        if(c->end()-curr<d||d<-(curr-c->begin()))throw out_of_bounds();
        return Checked_iter(c,curr+d);
    }
 
    reference operator[](difference_type d)const//только для итераторов произвольного доступа
    {
        if(c->end()-curr<=d||d<-(curr-c->begin()))throw out_of_bounds();
        return curr[d];
    }
 
    Checked_iter operator++ ()//префиксный ++
    {
        if(curr==c->end())throw out_of_bounds();
        ++curr;
        return *this;
    }
 
    Checked_iter operator++(int)//постфиксный ++
    {
        Checked_iter tmp=*this;
        ++*this;//проверяется префиксным ++
        return tmp;
    }
 
    Checked_iter operator--()//префиксный
    {
        if(curr==c->begin())throw out_of_bounds();
        --curr;
        return *this;
    }
 
    Checked_iter operator--(int)//постфиксный --
    {
        Checked_iter tmp=*this;
        --*this;//проверяется префиксным --
        return tmp;
    }
 
    difference_type index()const {return curr-c->begin();}//только произвольный доступ
    Iter unchecked() const {return curr;}
    //+,-,< и т.д.(параграф 19.6[6])
};
 
int main()
{
    cout <<"Chacked_iter"<<endl;
    list<string> ls;
    ls.push_back("hellow");
    ls.push_back("world");
 
    Checked_iter<list<string> > p(ls,ls.begin());
    try
    {
        cout <<*p<<endl;
        ++p;
        cout <<*p<<endl;
        ++p;
        cout <<*p<<endl;
    }
    catch(out_of_bounds)
    {
        cout <<"event be except"<<endl;
    }
 
    return 0;
}


И тут повозникало немножко вопросов:
C++
1
2
3
4
5
reference operator[](difference_type d)const//только для итераторов произвольного доступа
    {
        if(c->end()-curr<=d||d<-(curr-c->begin()))throw out_of_bounds();
        return curr[d];
    }
Вот этот кусок кода не сильно понятен. Вот что такое difference_type???? Я так думаю это какой то typedef из iterator_traits, да и вообще что такое iterator_traits???? Это я как бы понял если мы наследуем от iterator, то мы указываем одну из категорий итераторов, а когда от iterator_traits???? Он просто на фонарь сам определяет какой у нас итератор? То есть как бы содержит в себе все типы итераторов.

Вот эта строчка несильно понятна
C++
1
2
if(c->end()-curr<=d||d<-(curr-c->begin()))throw out_of_bounds();
        return curr[d];
с->end()-curr тут вроде ясно должно вернутся int да и вообще не ясно что будет если от конца последовательности отнять текущий итератор? Я знаю что будет если от итератора который указывает допустим на третий элемент отнять указатель на начало, то вернется 2 (или 3).

Еще вот эта вот штуковина
C++
1
struct out_of_bounds{};
Это я уже сам ее определил, потому что не нашел в <stdexcept> и в <exception> out_of_bounds. Его наверное нужно самому определять?

Еще к этому итератору самому нужно добавить операции +,-,< и т.д.
Вот как мне это сделать? Что под операцией '+' понимается для итераторов? Это что мне нужно, если допустим один итератор указывает на второй элемент, а другой на третий, то когда я прибавлю один итератор к другому у меня должен получится третий итератор который будет указывать на пятый элемент (2+3) ??? А операция '<' это что если it1 указывает на второй элемент, а it2 на третий, то когда it1<it2 должно вернутся true?????

Добавлено через 25 минут
C++
1
d<-(curr-c->begin())
Тут строчка не сильно ясна, это что унарный минус???
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.07.2013, 04:13     Checked_iter
Посмотрите здесь:

C++ Checked_Iter

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.07.2013, 18:15  [ТС]     Checked_iter #21
Цитата Сообщение от gray_fox Посмотреть сообщение
Не знаю, у меня нет сейчас VS...
Да разобрался то окно антивирус подвесил, а так все норм, программка заработала.

Добавлено через 9 минут
Цитата Сообщение от Tulosba Посмотреть сообщение
В общем случае разница считается в кол-ве элементов типа, на который указывает итератор, а не в кол-ве байт.
Ты хочешь сказать что в общем случае первый элемент 2000, второй 2001, третий 2002 и когда отнимим 2001 - 2000 мы как раз и получим 1?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
26.07.2013, 19:25     Checked_iter #22
Дабы, без плясок с Debug/Release можно просто задефайнить.
C++
1
#define _ITERATOR_DEBUG_LEVEL 0
перед инклудами и все будет окей.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.07.2013, 19:41  [ТС]     Checked_iter #23
ForEveR, Молодец шаришь!
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
26.07.2013, 20:29     Checked_iter #24
ninja2,

Не по теме:

Спасибо, о, Гуру

Yandex
Объявления
26.07.2013, 20:29     Checked_iter
Ответ Создать тему
Опции темы

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