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

ЖАНРЫ

Освой самостоятельно С++ за 21 день.

Либерти Джесс

Шрифт:

Пропустим пока функцию main и рассмотрим функцию StwtMap, которая открывает доступ к объектам карты с помощью константного итератора. Выражение ci->first (строка 109) указывает на ключ (имя студента), а выражение ci->second — на объект класса Student.

В строках 81-84 создаются четыре объекта класса Student. Класс MathClass определяется как экземпляр класса SchoolClass (строка 86), а в строках 87-90 уже имеющиеся четыре студента добавляются в класс MathClass:

map_object[key_value] = object_value;

Для добавления в карту пары ключ—значение

можно было бы также использовать функции push_back или insert (за более подробной информацией обратитесь к документации, прилагаемой к вашему компилятору).

После добавления к карте всех объектов класса Student можно обращаться к любому из них, используя их ключевые значения. В строках 95 и 96 для считывания записи, относящейся к студенту Биллу (объекту Bill), используется выражение MathClass["Bill"].

Другие ассоциативные контейнеры

Класс-контейнер мультикарты — это класс карты, не ограниченный уникальностью ключей. Это значит, что одно и то же ключевое значение могут иметь не один, а несколько элементов.

Класс-контейнер множества также подобен классу карты. Единственное отличие в том, что его элементы представляют собой не пары ключ-значение, а только ключи.

Наконец, класс-контейнер мультимножества — это класс множества, который позволяет иметь несколько ключевых значений.

Классы алгоритмов

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

Стандартные алгоритмы определены в файле <algorithm> в пространстве имен std.

Чтобы понять, как работают стандартные алгоритмы, необходимо познакомиться с понятием объектов функций. Объект функции — это экземпляр класса, в котором определен перегруженный оператор вызова функции. В результате этот класс может вызываться как функция. Использование объекта функции показано в листинге 19.11.

Листинг 19.11. объект функции

1: #include <iostream>

2: using namespace std;

3:

4: template<class T>

5: class Print {

6: public:

7: void operator(const T& t)

8: {

9: cout << t << " ";

10: }

11: };

12:

13: int main

14: {

15: Print<int> DoPrint;

16: for (int i = 0; i < 5; ++i)

17: DoPrint(i);

18: return 0;

19: }

Результат: 0 1 2 3 4

Анализ:

В строках 4—11 определяется шаблонный класс Print. Перегруженный в строках 7—10 оператор вызова функции принимает объект и перенаправляет его в стандартный поток вывода. В строке 15 определяется объект DoPrint как экземпляр класса Print. После этого, чтобы вывести на печать любые целочисленные значения, объект DoPrint можно использовать подобно обычной функции, как показано в строке 17.

Операции, не изменяющие последовательность

Операции, не изменяющие последовательность данных в структуре, реализуются с помощью таких функций, как for_each и find, search, count и т.д. В листинге 19.12 показан пример использования объекта функции и алгоритм for_each, предназначенный для печати элементов вектора.

Листинг 18.12. Использование алгоритма for_each

1: #include <iostream>

2: #include <vector>

3: #include <algorithm>

4: using namespace std;

5:

6: template<class T>

7: class Print

8: {

9: public:

10: void operator(const T& t)

11: {

12: cout << t << " ";

13: }

14: };

15:

16: int main

17: {

18: Print<int> DoPrint;

19: vector<int> vInt(5);

20:

21: for (int i = 0; i < 5; ++i)

22: vInt[i] = i * 3;

23:

24: cout << "for_each\n";

25: for_each(vInt.begin, vInt.end, DoPrint);

26: cout << "\n";

27:

28: return 0;

29: }

Результат:

for_each

0 3 6 9 12

Анализ: Обратите внимание, что все стандартные алгоритмы C++ определены в файле заголовка <algorithm>, поэтому следует включить его в нашу программу. Большая часть программы не должна вызывать никаких трудностей. В строке 25 вызывается функция for_each, чтобы опросить каждый элемент в векторе vInt. Для каждого элемента она вызывает объект функции DoPrint и передает этот элемент оператору DoPrint.operator, что приводит к выводу на экран значения данного элемента.

Алгоритмы изменения последовательности

Под изменением последовательности понимают изменение порядка элементов в структуре данных. Изменять последовательность способны операции, связанные с заполнением или переупорядочением коллекций. Алгоритм заполнения показан в листинге 19.13.

Листинг 19.13. Алгоритм изменения последовательности

1: #include <iostream>

2: #include <vector>

3: #include <algorithm>

4: using namespace std;

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