Литмир - Электронная Библиотека
A
A

 

Программирование. Принципы и практика использования C++ Исправленное издание - _001.png
 Что такое контейнер? Определение этого понятия можно найти в любом из указанных выше источников. Здесь лишь дадим неформальное определение. Итак, контейнер из библиотеки STL обладает следующими свойствами.

• Представляет собой последовательность элементов

[begin():end()]
.

• Операции над контейнером копируют элементы. Копирование можно выполнить с помощью присваивания или конструктора копирования.

• Тип элементов называется

value_type
.

• Контейнер содержит типы итераторов с именами

iterator
и
const_iterator
. Итераторы обеспечивают операции
*
,
++
(как префиксные, так и постфиксные),
==
и
!=
с соответствующей семантикой. Итераторы для класса
list
также предусматривают оператор
для перемещения по последовательности в обратном направлении; такие итераторы называют двунаправленными (bidirectional iterator). Итераторы для класса
vector
также предусматривает операции
––
,
[]
,
+
и
-
. Эти итераторы называют итераторами с произвольным доступом (random-access iterators) (см. раздел 20.10.1).

• Контейнеры имеют функции

insert()
и
erase()
,
front()
и
back()
,
push_back()
и
pop_back()
,
size()
и т.д.; классы
vector
и
map
также обеспечивают операцию индексирования (например, оператор
[]
).

• Контейнеры обеспечивают операторы (

==
,
!=
,
<
,
<=
,
>
и
>=
) для сравнения элементов. Контейнеры используют лексикографическое упорядочивание для операций
<
,
<=
,
>
и
>=
; иначе говоря, они сравнивают элементы, чтобы начинать перемещение с первого элемента.

• Цель этого списка — дать читателям некий обзор. Более детальная информация приведена в приложении Б. Более точная спецификация и полный список операций приведены в книге The C++ Programming Language или в стандарте.

Некоторые типы данных имеют многие свойства стандартных контейнеров, но не все. Мы иногда называем их “почти контейнерами”. Наиболее интересными среди них являются следующие.

Программирование. Принципы и практика использования C++ Исправленное издание - _235.png

Кроме того, многие люди и организации разрабатывают собственные контейнеры, удовлетворяющие или почти удовлетворяющие требованиям стандарта.

 

Программирование. Принципы и практика использования C++ Исправленное издание - _001.png
 Если у вас есть сомнения, используйте класс
vector
. Если у вас нет весомых причин не делать этого, используйте класс
vector
.

20.10.1. Категории итераторов

Мы говорили об итераторах так, будто все они являются взаимозаменяемыми. Однако они эквивалентны только с точки зрения простейших операций, таких как перемещение по последовательности с однократным считыванием каждого элемента. Если вы хотите большего, например перемещаться в обратном направлении или обеспечить произвольный доступ, то вам нужны более совершенные итераторы.

Программирование. Принципы и практика использования C++ Исправленное издание - _236.png

Глядя на предусмотренные операции, легко убедиться в том, что вместо итераторов для записи или чтения можно использовать двунаправленный итератор. Кроме того, двунаправленный итератор также является однонаправленным, а итератор с произвольным доступом — двунаправленным. В графическом виде категории итераторов можно изобразить следующим образом:

Программирование. Принципы и практика использования C++ Исправленное издание - _237.png

Обратите внимание на то, что категории итераторов не являются классами. Это не иерархия классов, реализованных с помощью наследования.

Задание

1. Определите массив чисел типа

int
с десятью элементами { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }.

2. Определите объект класса

vector<int>
с этими же десятью элементами.

3. Определите объект класса

list<int>
с этими же десятью элементами.

4. Определите второй массив, вектор и список, каждый из которых инициализируется первым массивом, вектором или списком соответственно.

5. Увеличьте значение каждого элемента в массиве на два; увеличьте значение каждого элемента в массиве на три; увеличьте значение каждого элемента в массиве на пять.

6. Напишите простую операцию

copy()

template<class Iter1, class Iter2>

Iter2 copy(Iter f1, Iter1 e1, Iter2 f2);

копирующую последовательность

[f1,e1]
в последовательность
[f2,f2+(e1–f1)]
и, точно так же, как стандартная библиотечная функция копирования, возвращающую число
f2+(e1–f1)
. Обратите внимание на то, что если
f1==e1
, то последовательность пуста и копировать нечего.

7. Используйте вашу функцию

copy()
для копирования массива в вектор или списка — в массив.

8. Используйте стандартную библиотечную функцию

find()
для того, чтобы убедиться, что вектор содержит значение
3
, и выведите на экран соответствующую позицию этого числа в векторе, если это число в нем есть. Используйте стандартную библиотечную функцию
find()
, чтобы убедиться, что список содержит значение
27
, и выведите на экран соответствующую позицию этого числа в списке, если это число в нем есть. Позиция первого элемента равна нулю, позиция второго элемента равна единице и т.д. Если функция
find()
возвращает итератор, установленный на конец последовательности, то значение в ней не найдено. Не забывайте тестировать программу после каждого этапа.

Контрольные вопросы

1. Почему программы, написанные разными людьми, выглядят по-разному? Приведите примеры.

284
{"b":"847443","o":1}