class DarkRaha extends com { // разработка приложений
            String a="Главная" b="Контакты" c="О сайте"
};

основы С++

STL

реализация STL
обзор
строки
потоки ввода/вывода
Форматирование ввода/вывода
Функции и методы потоков
Файловые потоки
класс vector
очередь
стек
отображения
итераторы
функциональные объекты
алгоритмы (1)
алгоритмы (2)
класс valarray

Справочник по C++ STL

Итераторы

Для доступа к элементам некоторого множества элементов алгоритмы stl используют специальные объекты, называемые итераторами. В контейнерных типах stl они доступны через методы класса (например, begin() в шаблоне класса vector). Функциональные возможности указателей и итераторов близки, так что обычный указатель тоже может использоваться как итератор.

категории итераторов

операции доступные итераторам

Операция RIt InIt OutIt FIt BIt
*it + + - + +
*it=val - - + - -
it->mem + + - + +
++it + + + + +
it++ + + + + +
--it + - - - +
it-- + - - - +
it1==it2 + + - + +
it1!=it2 + + - + +
con () + - - + +
con (it) + + + + +
it[] + - - - -
it+=val + - - - -
it-=val + - - - -
it+val + - - - -
it-val + - - - -
it1-it2 + - - - -
it1<it2 + - - - -
it1>it2 + - - - -
it1<=it2 + - - - -
it1>=it2 + - - - -

Кроме операций для итераторов определены три функции:

класс iterator_traits

Все характеристики итератора собраны в классе iterator_traits.


template <class T>
struct iterator_traits {
   typedef typename T::value_type         value_type; // тип значения элемента
   typedef typename T::difference_type    difference_type; // тип разности итераторов
   typedef typename T::iterator_category  iterator_category; // категория
   typedef typename T::pointer            pointer; // тип указателя
   typedef typename T::reference          reference; // тип ссылки
};

Для указания типа итератора, определены пять пустых типов меток.


struct output_iterator_tag {};
struct input_iterator_tag {};
struct forward_iterator_tag: public input_iterator_tag {};
struct bidirectional_iterator_tag: public forward_iterator_tag {};
struct random_access_iterator_tag: public bidirectional_iterator_tag {};

Также определена специализация шаблона iterator_traits, позволяющая использовать обычные указатели в качестве итераторов.

пользовательский итератор

Пользовательские итераторы создаются как наследники от шаблона класса iterator. Для использования итератора в алгоритмах stl определяются указанные выше операции (по необходимости перегружаются и те три функции).


#include <iterator>

// type - имя типа элементов
// с которыми будет работать итератор
class MyIt: 
  public std::iterator 
     <std::bidirectional_iterator_tag, type> {
        ...
};

// а можно задать все детально
class MyIterator: 
  public std::iterator 
     <std::bidirectional_iterator_tag,
         type, ptrdiff_t, type*, type&> {
      ...
};

пример итератора

В С++ двухмерный массив часто представляют в виде одномерного, используя для индексации по x и y формулу x+y*w, где w ширина массива. Ниже приведен простой неоптимизированный итератор работающий с подобными массивами. В качестве объекта массива может выступать любой контейнерный тип с операцией индексации.

С помощью этого итератора вы можете работать с 'окнами' внутри двухмерного массива. Так здесь с помощью fill заполняется окно 3x3 с координатами (2,2) внутри массива 10x10.


#include <iostream>
#include <iterator>
#include <algorithm>
using namespace std;

// T - тип объекта, содержащего элементы
// Tval - тип элементов
template <typename T,typename Tval>
class It2d: public std::iterator
     <std::forward_iterator_tag, T> {
protected:
T& datab;   // объект с элементами, и с операцией[]
int posbeg; // с какого элемента
int width;  // полная ширина
int w;      // ширина окна
int i;      // текущая позиция

public:
It2d(T& ddatab, int pposbeg, int wwidth,
     int ww, int pos=0): datab(ddatab){
width=wwidth;
w=ww;
posbeg=pposbeg;
i=pos;
}


It2d(const It2d<T,Tval>& a):datab(a.datab){
width=a.width;
w=a.w;
i=a.i;
posbeg=a.posbeg;
}

//----------------------------------
Tval& operator *(){
    return datab[posbeg+i%w+i/w*width];
    }

It2d<T,Tval>&operator ++(){
    ++i;
    return *this;
    }

It2d<T,Tval>& operator ++(int a){
    ++i;
    return *this;
    }

bool operator ==(It2d<T,Tval> &it){
return datab==it.datab && i==it.i &&
       w==it.w && width==it.width;
}

bool operator !=(It2d<T,Tval>&it){
    return !(*this==it);
    }
};

void out(int*data){
for(int i=0;i<10;i++){
  for(int j=0;j<10;j++)
    cout<<data[j+i*10];
cout<<endl;
}
}

int main(){
int *data=new int[10*10];
std::fill(data,data+100,1);
out(data);
It2d<int*,int> begin(data,10*2+2,10,3);
It2d<int*,int> end(data,10*2+2,10,3,9);
std::fill(begin,end,2);
cout<<"=========="<<endl;
out(data);
return 0;
}

Рейтинг@Mail.ru