Чтение онлайн

ЖАНРЫ

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

Документацию о реализации библиотеки STL компании Rogue Wave можно найти на веб-странице www2.roguewave.com/support/docs/index.cfm.

Вы чувствуете себя обманутым? Полагаете, что мы должны описать все контейнеры и показать, как их использовать? Это невозможно. Существует слишком много стандартных возможностей, полезных приемов и библиотек, чтобы описать их в одной книге. Программирование слишком богато возможностями, чтобы их мог освоить один человек. Кроме того, часто программирование — это искусство. Как программист вы должны привыкнуть искать информацию о возможностях языка, библиотеках и технологиях. Программирование — динамичная и быстро развивающаяся отрасль, поэтому необходимо довольствоваться тем,
что вы знаете, и спокойно относиться к тому, что существуют вещи, которых вы не знаете. “Искать в справочнике” — это вполне разумный ответ на многие вопросы. По мере увеличения вашего опыта, вы будете все чаще поступать именно так.

С другой стороны, вы обнаружите, что, освоив классы

vector
,
list
и
map
, а также стандартные алгоритмы, описанные в главе 21, вы легко научитесь работать с остальными контейнерами из библиотеки STL. Вы обнаружите также, что знаете все, что требуется для работы с нестандартными контейнерами, и сможете их программировать сами.

Что такое контейнер? Определение этого понятия можно найти в любом из указанных выше источников. Здесь лишь дадим неформальное определение. Итак, контейнер из библиотеки 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 или в стандарте.

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

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

Если у вас есть сомнения, используйте класс
vector
. Если у вас нет весомых причин не делать этого, используйте класс
vector
.

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

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

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

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

Задание

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. Почему программы, написанные разными людьми, выглядят по-разному? Приведите примеры.

2. Какие простые вопросы мы обычно задаем, думая о данных?

3. Перечислите разные способы хранения данных?

4. Какие основные операции можно выполнить с коллекцией данных?

5. Каких принципов следует придерживаться при хранении данных?

6. Что такое последовательность в библиотеке STL?

7. Что такое итератор в библиотеке STL? Какие операции поддерживают итераторы?

Поделиться с друзьями: