C++ Учебник по STL

Стандартная библиотека шаблонов C++ (STL) — это мощный набор шаблонных классов и функций C++, который предоставляет ряд обобщённых, многократно используемых алгоритмов и структур данных.

Дизайн STL основан на обобщённом программировании, что означает, что шаблоны можно использовать для написания кода, независимого от любого конкретного типа данных.

STL делится на несколько компонентов, включая контейнеры, итераторы, алгоритмы, функциональные объекты и адаптеры и т. д.

Преимущества использования STL:

  • Повторное использование кода: STL предоставляет большое количество обобщённых структур данных и алгоритмов, сокращая работу по написанию повторяющегося кода.
  • Оптимизация производительности: Алгоритмы и структуры данных в STL оптимизированы для обеспечения наилучшей производительности.
  • Обобщённое программирование: Используя шаблоны, STL поддерживает обобщённое программирование, позволяя алгоритмам и структурам данных применяться к любому типу данных.
  • Простота сопровождения: Дизайн STL делает код более модульным и более простым для чтения и сопровождения.

Ядро стандартной библиотеки шаблонов C++ включает следующие важные компоненты:

Компоненты Описание
Контейнеры

Контейнеры — одни из самых базовых компонентов в STL. Они предоставляют различные структуры данных, включая vector, list, queue, stack, set, map и так далее. Эти контейнеры имеют разные характеристики и назначения, поэтому можно выбрать подходящий контейнер исходя из фактических потребностей.

Алгоритмы STL предоставляет большое количество алгоритмов для выполнения различных операций над элементами в контейнерах, включая сортировку, поиск, копирование, перемещение, преобразование и т. д. При использовании этих алгоритмов не нужно заботиться о конкретном типе контейнера; достаточно указать диапазон, над которым будут выполняться операции.
Итераторы Итераторы используются для обхода элементов в контейнерах, позволяя обращаться к элементам единообразным способом, не заботясь о внутренних деталях реализации контейнера. STL предоставляет множество типов итераторов, включая итераторы произвольного доступа, двунаправленные итераторы, однонаправленные итераторы и итераторы ввода/вывода, среди прочих.
Функциональные объекты Функциональные объекты — это объекты, которые можно вызывать как функции и использовать для различных операций в алгоритмах. STL предоставляет множество функциональных объектов, включая унарные функциональные объекты, бинарные функциональные объекты, предикаты и другие, чтобы удовлетворять различные потребности.
Адаптеры Адаптеры используются для адаптации одного контейнера или итератора к другому контейнеру или итератору для выполнения конкретных требований. STL предоставляет множество адаптеров, включая адаптер стека, адаптер очереди и адаптер очереди с приоритетом, среди прочих.

Все эти компоненты поставляются с богатым набором предопределённых функций, помогая нам просто справляться со сложными задачами.


Контейнер

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

Контейнеры в STL можно разделить на три категории:

1. Последовательные контейнеры: хранят последовательности элементов и допускают двунаправленный обход.

  • std::vector: динамический массив, поддерживает быстрый произвольный доступ.
  • std::deque: двусторонняя очередь, поддерживает быструю вставку и удаление.
  • std::list: связанный список, поддерживает быструю вставку и удаление, но не поддерживает произвольный доступ.

2. Ассоциативные контейнеры: хранят пары ключ-значение. Каждый элемент имеет ключ и значение, а элементы упорядочены по ключам.

  • std::set: множество, дублирующиеся элементы не допускаются.
  • std::multiset: мультимножество, позволяет нескольким элементам иметь один и тот же ключ.
  • std::map: отображение, каждый ключ сопоставляется со значением.
  • std::multimap: multimap, хранит пары ключ-значение (pair), где ключи не уникальны и значения могут повторяться, что позволяет одному ключу соответствовать нескольким значениям.

3. Неупорядоченные контейнеры (представлены в C++11): хеш-таблицы, поддерживают быстрый поиск, вставку и удаление.

  • std::unordered_set: неупорядоченное множество.
  • std::unordered_multiset: неупорядоченное мультимножество.
  • std::unordered_map: неупорядоченная карта.
  • std::unordered_multimap: неупорядоченная мультикарта.

Следующая программа демонстрирует контейнер vector (стандартный шаблон C++), который очень похож на массив. Единственное отличие в том, что когда vector нужно увеличить свой размер, он автоматически управляет собственными требованиями к памяти:

Пример

#include <iostream> #include <vector> using namespace std; int main() { // Создать vector для хранения int vector<int> vec; int i; // Отобразить исходный размер vec cout << "размер vector = " << vec.size() << endl; // Добавить 5 значений в vector for(i = 0; i < 5; i++){ vec.push_back(i); } // Отобразить размер vec после расширения cout << "расширенный размер вектора = " << vec.size() << endl; // Доступ к 5 значениям в векторе for(i = 0; i < 5; i++){ cout << "значение vec [" << i << "] = " << vec[i] << endl; } // Использование итератора для доступа к значениям vector<int>::iterator v = vec.begin(); while( v != vec.end()) { cout << "значение v = " << *v << endl; v++; } return 0; }

Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:

vector size = 0
extended vector size = 5
value of vec [0] = 0
value of vec [1] = 1
value of vec [2] = 2
value of vec [3] = 3
value of vec [4] = 4
value of v = 0
value of v = 1
value of v = 2
value of v = 3
value of v = 4

Относительно различных функций, использованных в приведённом выше примере, следует отметить несколько моментов:

  • Функция-член push_back( ) вставляет значение в конец вектора, при необходимости увеличивая размер вектора.
  • Функция size( ) отображает размер вектора.
  • Функция begin( ) возвращает итератор, указывающий на начало вектора.
  • Функция end( ) возвращает итератор, указывающий на конец вектора.

STL — неотъемлемая часть программирования на C++. Она значительно расширяет функциональность C++, позволяя программистам писать более эффективный и более читаемый код.

Освоение использования STL очень важно для любого программиста C++.

Другие расширения