Файл: Неизвестные типы и пространство неизвестных имен. Динамическое определение типов. Операторы переключения типов. Создание пространства новых имен. Буферизированный вход и выход. Содержание.pptx
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 30.11.2023
Просмотров: 21
Скачиваний: 6
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
PRESENTATION
- Неизвестные типы и пространство неизвестных имен. Динамическое определение типов. Операторы переключения типов. Создание пространства новых имен. Буферизированный вход и выход. Содержание: Динамическая идентификация типов. Оператор typeid().
- Динамическая идентификация типов. Операторы dynamic_cast, const_cast, reinterpret_cast, static_cast.
- Пространства имен. Ключевые слова namespace, using. Правила создания пространства имен. Глобальное пространство имен. Динамическая идентификация типов. Оператор typeid(). 1. Понятие о динамической идентификации типа. В целях поддержания динамического полиморфизма в языке C++ введена динамическая идентификация типа (RTTI – Run-Time Type Identification). Эта динамическая идентификация позволяет идентифицировать тип объекта при выполнении программы. Основным средством динамической идентификации типа является оператор typeid(). С целью обеспечения лучшего приведения типов в последние версии C++ включены дополнительные операторы приведения типа. К этим операторам относятся: dynamic_cast; const_cast; reinterpret_cast; static_cast. Также язык C++ имеет стандартный оператор приведения типа, который имеет вид: (type)expression
- 2. Идентификация типа. Операор typeid() Язык программирования C++ поддерживает динамический полиморфизм благодаря сочетанию наследования, виртуальных функций и использования указателя на базовый класс. В иерархии классов указатель на базовый класс может указывать на экземпляр любого класса в иерархии. Поэтому не всегда можно предположить, на объект какого класса иерархии указывает указатель. Идентификацию типа нужно производить по ходу выполнения программы. Для идентификации типа в языке C++ используется оператор typeid(). Этот оператор имеет две формы использования: typeid(object) – определение характеристик типа объекта или переменной с именем object; typeid(type) – определение характеристик типа с именем type. Оператор typeid() возвращает ссылку на объект типа type_info. Класс type_info описывает тип объекта и имеет следующие внутренние члены: Операторные функции bool operator==(const type_info& obj); bool operator!=(const type_info& obj); Эти функции перегружают операторы сравнения == и !=. Функцию const char* name(); Эта функция возвращает указатель на имя определяемого типа. Функцию bool before(const type_info& obj); Эта функция возвращает true, если вызывающий объект предшествует объекту, использованному в качестве параметра. Чтобы использовать оператор typeid(), нужно подключить модуль typeinfo. #include
Безусловно, наиболее часто используемым функционалом библиотеки STL являются контейнерные классы (или как их еще называют — «контейнеры»). Библиотека STL содержит много разных контейнерных классов, которые можно использовать в разных ситуациях. Если говорить в общем, то контейнеры STL делятся на три основные категории:
последовательные;
ассоциативные;
адаптеры.
Сейчас сделаем их краткий обзор.
Оглавление:
- Последовательные контейнеры
- Ассоциативные контейнеры
- Адаптеры
Последовательные контейнеры
Последовательные контейнеры (или «контейнеры последовательности») — это контейнерные классы, элементы которых находятся в последовательности. Их определяющей характеристикой является то, что вы можете добавить свой элемент в любое место контейнера. Наиболее распространенным примером последовательного контейнера является массив: при добавлении 4 элементов в массив, эти элементы будут находиться (в массиве) в точно таком же порядке, в котором вы их добавили.
Контейнеры STL
Начиная с C++11, STL содержит 6 контейнеров последовательности:
std::vector;
std::deque;
std::array;
std::list;
std::forward_list;
std::basic_string.
Класс vector (или просто «вектор») — это динамический массив, способный увеличиваться по мере необходимости для содержания всех своих элементов. Класс vector обеспечивает произвольный доступ к своим элементам через оператор индексации [], а также поддерживает добавление и удаление элементов.
В следующей программе мы добавляем 5 целых чисел в вектор и с помощью перегруженного оператора индексации [] получаем к ним доступ для их последующего вывода
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include #include int main() { std::vector for (int count=0; count < 5; ++count) vect.push_back(10 - count); // добавляем числа в конец массива for (int index=0; index < vect.size(); ++index) std::cout << vect[index] << ' '; std::cout << '\n'; |
Класс deque (или просто «дек») — это двусторонняя очередь, реализованная в виде динамического массива, который может расти с обоих концов. Например:
#include
#include
int main()
{
std::deque
for (int count=0; count < 4; ++count)
{
deq.push_back(count); // вставляем числа в конец массива
deq.push_front(10 - count); // вставляем числа в начало массива
}
for (int index=0; index < deq.size(); ++index)
std::cout << deq[index] << ' ';
std::cout << '\n';
}
List (или просто «список») — это двусвязный список, каждый элемент которого содержит 2 указателя: один указывает на следующий элемент списка, а другой — на предыдущий элемент списка. List предоставляет доступ только к началу и к концу списка — произвольный доступ запрещен. Если вы хотите найти значение где-то в середине, то вы должны начать с одного конца и перебирать каждый элемент списка до тех пор, пока не найдете то, что ищете. Преимуществом двусвязного списка является то, что добавление элементов происходит очень быстро, если вы, конечно, знаете, куда хотите добавлять. Обычно для перебора элементов двусвязного списка используются итераторы.
Хотя о классе string (и wstring) обычно не говорят, как о последовательном контейнере, но он, по сути, таковым является, поскольку его можно рассматривать как вектор с элементами типа char (или wchar).
Ассоциативные контейнеры
Ассоциативные контейнеры — это контейнерные классы, которые автоматически сортируют все свои элементы (в том числе и те, которые добавляете вы). По умолчанию ассоциативные контейнеры выполняют сортировку элементов, используя оператор сравнения <.
set — это контейнер, в котором хранятся только уникальные элементы, и повторения запрещены. Элементы сортируются в соответствии с их значениями.
multiset — это set, но в котором допускаются повторяющиеся элементы.
map (или «ассоциативный массив») — это set, в котором каждый элемент является парой «ключ-значение». «Ключ» используется для сортировки и индексации данных и должен быть уникальным, а «значение» — это фактические данные.
multimap (или «словарь») — это map, который допускает дублирование ключей. Все ключи отсортированы в порядке возрастания, и вы можете посмотреть значение по ключу.
Адаптеры
Адаптеры — это специальные предопределенные контейнерные классы, которые адаптированы для выполнения конкретных заданий. Самое интересное заключается в том, что вы сами можете выбрать, какой последовательный контейнер должен использовать адаптер.
stack (стек) — это контейнерный класс, элементы которого работают по принципу LIFO (англ. «Last In, First Out» = «последним пришел, первым ушел»), т.е. элементы добавляются (вносятся) в конец контейнера и удаляются (выталкиваются) оттуда же (из конца контейнера). Обычно в стеках используется deque в качестве последовательного контейнера по умолчанию (что немного странно, поскольку vector был бы более подходящим вариантом), но вы также можете использовать vector или list.
queue (очередь) — это контейнерный класс, элементы которого работают по принципу FIFO (англ. «First In, First Out» = «первым пришел, первым ушел»), т.е. элементы добавляются (вносятся) в конец контейнера, но удаляются (выталкиваются) из начала контейнера. По умолчанию в очереди используется deque в качестве последовательного контейнера, но также может использоваться и list.
Контейнеры и итераторы
Контейнер container — класс, объекты которого способны хранить набор однотипных значений (обобщение понятия “массив”). Контейнер предоставляет средства доступа к своему содержимому. В Стандартной библиотеке C++ эти средства доступа строятся на обобщении понятия “указатель на элемент массива”, которое носит название итератор iterator.
Пара итераторов задаёт диапазон range — определение последовательности значений, которую можно перечислить, передвигая итератор вперёд, начиная с первого элемента, на который указывает первый итератор в паре, и до тех пор, пока не будет встречен второй итератор в паре, обозначающий конец последовательности и указывающий на фиктивный элемент, как бы стоящий в последовательности сразу за последним элементом.
Последовательность может представлять собой контейнер, часть контейнера, массив, файл или генерироваться “на ходу”.
Пример диапазона с массивом:
char data[] = "Hello, world!"; // Диапазон с 7-го элемента по 12-й содержит слово "world". auto begin = data + 7; // Начало диапазона -- первый итератор в паре. auto end = data + 12; // Конец диапазона -- второй итератор в паре. assert(end - begin == 5); // Расстояние между итераторами == количеству элементов в диапазоне. // Перечислим подряд все элементы диапазона. while (begin != end) cout.put(*begin++); // > world