
- •Учебное пособие
- •Введение
- •Объектно-ориентированный подход
- •Объектно-ориентированное программирование Абстрактные типы данных
- •Базовые принципы объектно-ориентированного программирования
- •Простейший ввод и вывод
- •Объект cout
- •Манипуляторы hex и oct
- •Другие манипуляторы
- •Объект cin
- •Операторы для динамического выделения и освобождения памяти (new и delete)
- •Базовые конструкции объектно-ориентированных программ Объекты
- •Понятие класса
- •Конструктор копирования
- •Конструктор explicit
- •Указатели на компоненты класса
- •Встроенные функции (спецификатор inline)
- •Организация внешнего доступа к локальным компонентам класса (спецификатор friend)
- •Вложенные классы
- •Static-члены (данные) класса
- •Указатель this
- •Компоненты-функции static и const
- •Proxi-классы
- •Параметры ссылки
- •Независимые ссылки
- •Практические приемы ограничения числа объектов класса
- •Наследование (производные классы)
- •Конструкторы и деструкторы при наследовании
- •Виртуальные функции
- •Абстрактные классы
- •Виртуальные деструкторы
- •Множественное наследование
- •Виртуальное наследование
- •Перегрузка функций
- •Перегрузка операторов
- •Перегрузка бинарного оператора
- •Перегрузка унарного оператора
- •Дружественная функция operator
- •Перегрузка оператора []
- •Перегрузка оператора ()
- •Перегрузка операторов new и delete
- •Преобразование типа
- •Явные преобразования типов
- •Преобразования типов, определенных в программе
- •Шаблоны Параметризированные классы
- •Передача в шаблон класса дополнительных параметров
- •Шаблоны функций
- •Совместное использование шаблонов и наследования
- •Шаблоны класса и friend
- •Некоторые примеры использования шаблона класса Реализация smart-указателя
- •Классы поддерживающие транзакции
- •Задание значений параметров класса по умолчанию
- •Пространства имен
- •Ключевое слово using как директива
- •Ключевое слово using как объявление
- •Псевдоним пространства имен
- •Организация ввода-вывода
- •Состояние потока
- •Строковые потоки
- •Организация работы с файлами
- •Организация файла последовательного доступа
- •Создание файла произвольного доступа
- •Основные функции классов ios, istream, ostream
- •Основы обработки исключительных ситуаций
- •Перенаправление исключительных ситуаций
- •Исключительная ситуация, генерируемая оператором new
- •Генерация исключений в конструкторах
- •Задание собственной функции завершения
- •Спецификации исключительных ситуаций
- •Задание собственного неожиданного обработчика
- •Иерархия исключений стандартной библиотеки
- •Стандартная библиотека шаблонов (stl) Общее понятие о контейнере
- •Общее понятие об итераторе
- •Категории итераторов
- •Основные итераторы
- •Вспомогательные итераторы
- •Операции с итераторами
- •Контейнерные классы Контейнеры последовательностей
- •Контейнер последовательностей vector
- •Контейнер последовательностей list
- •Контейнер последовательностей deque
- •Ассоциативные контейнеры
- •Ассоциативный контейнер multiset
- •Ассоциативный контейнер set
- •Ассоциативный контейнер multimap
- •Ассоциативный контейнер map
- •Адаптеры контейнеров
- •Адаптеры stack
- •Адаптеры queue
- •Адаптеры priority_queue
- •Пассивные и активные итераторы
- •Алгоритмы
- •Алгоритмы сортировки sort, partial_sort, sort_heap
- •Алгоритмы поиска find, find_if, find_end, binary_search
- •Алгоритмы fill, fill_n, generate и generate_n
- •Алгоритмы equal, mismatch и lexicographical_compare
- •Математические алгоритмы
- •Алгоритмы работы с множествами
- •Алгоритмы swap, iter_swap и swap_ranges
- •Алгоритмы copy, copy_backward, merge, unique и reverse
- •Примеры реализации контейнерных классов Связанные списки
- •Реализация односвязного списка
- •Реализация двусвязного списка
- •Реализация двоичного дерева
- •Литература
- •Вопросы по курсу ооп
- •220013, Минск, п.Бровки, 6.
Операции с итераторами
Существуют две важных операции для манипуляции ими. С одной из них - advance - мы познакомились в последнем примере. Это просто удобная форма инкрементирования итератора itr на определенное число n:
void advance (InputIterator& itr, Distance& n);
Вторая операция измеряет расстояние между итераторами first и second, возвращая полученное число через ссылку n:
void distance(InputIterator& first, InputIterator& second, Distance& n);
Контейнерные классы Контейнеры последовательностей
Стандартная библиотека С++ предоставляет три контейнера последовательностей – vector, list и deque. Первые два представляют собой классы, организованные по типу массивов, а последний реализует связанный список. Класс vector является одним из наиболее популярных контейнерных классов в STL, динамически изменяющим свои размеры.
Использование контейнера vector наиболее эффективно при добавлении элементов в конец контейнера. Для приложений, выполняющих частые вставки и удаления в конец и начало контейнера, более предпочтительным является deque. Если требуется выполнять вставки и удаление элементов в любое место контейнера, то обычно используется list.
Кроме перечисленных выше компонент-функций, общих для всех STL-контейнеров, контейнеры последовательностей имеют несколько особых: front и back - для возврата ссылки на первый и последний элемент в контейнере, push_back и pop_back – для вставки и удаления последнего элемента контейнера.
Контейнер последовательностей vector
Аналогично обычным массивам в С и С++ класс vector обеспечивает непрерывную область памяти для размещения данных. Следовательно, возможен доступ к любому элементу контейнера посредством индексации. В случае, если при добавлении новых элементов в контейнер объема выделенной памяти недостаточно, vector выделяет память большего размера. Выполняется копирование информации в выделенную область памяти и освобождение старой области памяти.
Контейнер vector поддерживает итераторы произвольного доступа, то есть все операции итераторов (табл. 4) могут быть применены к итератору контейнера vector. Все алгоритмы STL могут работать с контейнером vector.
В приводимой ниже программе демонстрируется использование некоторых компонент-функций класса vector.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <vector>
template<class T>
void PrintVector(const std::vector<T> &vect);
main()
{ std::vector<int> v,vv;
PrintVector(v);
v.push_back(2);
v.push_back(5);
v.push_back(7);
v.push_back(1);
v.push_back(9);
v[4]=3; // изменить значение 5-го элемента на 3
v.at(3)=6; // изменить значение 3-го элемента на 6
try{ v.at(5)=0; //
}
catch(std::out_of_range e){ //доступ к элементу вне массива (вектора)
cout<<"\nИсключение : "<<e.what();
}
PrintVector(v);
v.erase(v.begin() + 2); // удаление 3-го элемента (начальный индекс 0)
PrintVector(v);
v.insert(v.begin() + 3,7);// добавление 7 после 3-го элемента вектора
PrintVector(v);
vv.push_back(6);
v.swap(vv); // замена массивов v и vv
PrintVector(v);
PrintVector(vv);
vv.erase(vv.begin()+1,vv.end()-2); //удаление со 2-го по n-2 элементов
PrintVector(vv);
vv.clear(); // чистка всего вектора
PrintVector(vv);
return 0;
}
template<class T>
void PrintVector(const std::vector<T> &vect)
{ std::vector<T>::const_iterator pt;
if (vect.empty())
{ cout << endl << "Vector is empty." << endl;
return;
}
cout<<"ВЕКТОР :"
<<" Размер ="<<vect.size()
<<" вместимость ="<<vect.capacity()<<endl;
cout<<"содержимое :";
for(pt=vect.begin();pt!=vect.end();pt++)
cout<<*pt<<' ';
cout<<endl;
}
Инструкция
std::vector<int> v,vv;
определяет два экземпляра класса v и vv для хранения int чисел. При этом создаются два пустых контейнера с нулевым числом элементов и нулевой вместимостью (числом элементов, которые могут быть сохранены в контейнере). Компонента-функция push_back(), имеющаяся во всех контейнерах последовательностей, используется для добавления элемента в контейнер v. Инструкции
v[4]=3;
v.at(3)=6;
демонстрируют два способа индексирования контейнера vector (используются и для контейнера deque). Первая инструкция реализуется перегрузкой операции [], возвращающей либо ссылку на значение в требуемой позиции, либо константную ссылку на это значение, в зависимости от того, является ли контейнер константным. Следующая функция at() выполняет то же, осуществляя дополнительно проверку на выход индекса из диапазона. Функции size() и capacity() возвращают число элементов вектора (диапазон) и его вместимость. Вместимость удваивается каждый раз в том случае, когда при попытке разместить очередной элемент в контейнере все выделенное пространство памяти занято.
При добавлении первого элемента размер стал равен 1 вместимость 1, второго – размер 2 вместимость 2, третьего - 3 и 4 соответственно, четвертого - 4 и 8 и т.д. В примере приведена внешняя функция просмотра вектора и его размера и вместимости PrintVector(). Для прохода по вектору используется итератор pt:
std::vector<T>::const_iterator pt;
Этот итератор (const_iterator) допускает считывание, но не модификацию элементов контейнера vector. При проходе по вектору используются функции begin() и end(), доступные для всех контейнеров первого класса.
Кроме перечисленных выше в программе используются функции класса vector: clear(), empty() и swap().
Контейнер vector не должен быть пустым, иначе результаты функций front и back будут не определены.