Лекция 02 - Новые возможности С++.pptx
- Количество слайдов: 41
Новые возможности языка Си++
Операторы new и delete В состав языка вошли операторы new и delete, осуществляющие работу с динамической памятью на уровне языка Оператор new выделяет память под элемент или массив элементов Тип *p = new Тип() Тип *p = new Тип(инициализатор, . . . ) Тип *p = new Тип[кол-во элементов] Оператор delete освобождает память, выделенную ранее оператором new delete p. Object; delete [] p. Array;
Возможность объявления переменной при её первом использовании В отличие от языка C, локальные переменные в C++ могут быть объявлены в любом месте функции, а не только в начале блока Более того, это улучшает читаемость программы и является необходимым в ряде случаев Неизменным остается правило – переменная должна быть объявлена ДО ее первого использования Есть возможность объявления переменной цикла непосредственно в операторе for (int i = 0; i < 10; ++i) Время жизни такой переменной ограничено телом цикла (не соблюдается некоторыми старыми компияторами)
Перегрузка функций
Перегрузка функций Перегрузкой имени функции является его использование для обозначения разных операций над разными типами Если несколько функций выполняют одно и то же действие с объектами различных типов, имеет смысл дать им одинаковые имена
Пример #include
Функции с различным количеством аргументов Функции с одним именем могут иметь различное число аргументов В этом случае, будет вызвана та функция, количество формальных аргументов которой совпадает с количеством переданных параметров
Пример void Print(char ch) { putchar(ch); } void Print(char ch, int count) { while (count--) { putchar(ch); } } int main() { Print('!'); putchar('n'); Print('!', 5); putchar('n'); return 0; }
Выбор нужной функции Для выбора функции из имеющихся вариантов компилятор сравнивает типы фактических аргументов, указанные в вызове, с типами формальных аргументов всех описаний функций с данным именем В результате вызывается та функция, у которой типы формальных аргументов наилучшим образом сопоставились с параметрами вызова Типы возвращаемых значений функций не учитываются
Правила сопоставления параметров Правила сопоставления имеют следующие приоритеты (в порядке убывания): Точное сопоставление произошло без всяких преобразований типа или только с неизбежными преобразованиями Сопоставление с использованием стандартных целочисленных преобразований и преобразований с плавающей запятой char в int, short в int, float в double Сопоставление с использованием стандартных преобразований, определенных в §R. 4 int в double, derived * в base*, unsigned в int Сопоставление с использованием пользовательских преобразований §R. 12. 3 Сопоставление с использованием эллипсиса. . . в описании функции Выбирается та функция, у которой произошло сопоставление по наиболее приоритетному правилу
Возможные проблемы Если две или более функций с данным именем были сопоставлены по самому приоритетному правилу, компилятор выдаст сообщение об ошибке В этом случае требуется явно приводить аргументы к требуемым типам
Пример void Print(int number) { printf("%d", number); } void Print(double number) { printf("%. 15 f", number); } int main() { unsigned int arg = 2; Print(arg); // ошибка Print(static_cast
Стандартные значения параметров Некоторые функции могут принимать больше параметров, чем в самых простых и часто используемых случаях Для гибкого использования этих функций могут применяться необязательные параметры
#include
Ссылки Ссылку можно рассматривать как еще одно имя объекта Синтаксис <Тип> & означает ссылку на <Тип> Применение Задание параметров функций Перегрузка операций
Ссылки в качестве параметров функций При передаче параметра в функцию по ссылке, функция принимает не копию аргумента, а ссылку на него При сложных типах аргументов это может дать прирост в скорости вызова функции Измененное внутри функции значение формального параметра приведет к изменению значения переданного аргумента Использование ссылок может быть альтернативным способом возврата значения из функции Если функция не изменяет значение аргумента, будет иметь смысл передать его по константной ссылке
Пример 1 #include
Пример 2 struct Point { int x, y; }; void Print(Point const& pnt) { printf("(x: %d, y: %d)n", pnt. x, pnt. y); } int main() { Point pnt = {10, 20}; Print(pnt); return 0; }
Инициализация ссылки Ссылка должна быть обязательно проинициализирована Должен существовать объект на который она ссылается Синтаксис Тип & идентификатор = значение; Инициализация ссылки совершенно отличается от операции присваивания Будучи проинициализированной, присваивание ссылке нового значения изменяет значение ссылаемого объекта, а не значение ссылки
Пример #include
Ссылки на временные объекты При инициализации ссылки объектом другого типа компилятор создает временный объект нужного типа и использует его для инициализации ссылки На данный временный объект может ссылаться только константная ссылка То же самое происходит при инициализации ссылки значением константы Изменение значения объекта в данном случае не отражается на значении временного объекта
Пример int a = 1; int & ref. A = a; printf("a = %dn", a); ++ref. A; printf("Now a = %dnn", a); const double & ref. Double. A = a; printf("ref. Double. A = %fn", ref. Double. A); ++a; printf("Now a = %d, ref. Double. A = %fn", a, ref. Double. A); OUTPUT: a = 1 Now a = 2 ref. Double. A = 2. 00000 Now a = 3, ref. Double. A = 2. 00000
Пространства имен позволяют логически сгруппировать классы, переменные и функции в некоторые именованные области Позволяют избежать конфликта имен идентификаторов в различных модулях проекта Разбивают программу на функциональные единицы
#include
Стандартная библиотека шаблонов (STL) Программная библиотека, содержащая большое количество готового к использованию обобщенного кода Контейнеры Итераторы Алгоритмы Все контейнеры, алгоритмы и итераторы в STL объявлены в пространстве имен std Стандарт запрещает программисту объявлять свои типы в данном пространстве имен
Контейнеры Классы, предназначенные для хранения элементов определенного типа STL содержит классы обобщенных реализаций различных контейнеров, которые можно использовать с элементами различных типов В STL поддерживаются 2 вида контейнеров Последовательные Ассоциативные
Контейнеры в STL Последовательные контейнеры Строка (basic_string, wstring) Вектор (vector) Двусвязный список (list) Двусторонняя очередь (deque) Ассоциативные контейнеры карта (map, multimap) множество (set, multiset) Контейнеры-адаптеры Стек (stack) Очередь (queue) Очередь с приоритетом (priority_queue)
Строка std: : string Контейнер, предназначенный для хранения строк произвольной длины В качестве элементов строк могут выступать элементы типа char (string), wchar_t (wstring) или определяемые пользователем типы (basic_string) Данный контейнер автоматизирует задачу управления памятью, занимаемой символами строки и предоставляет набор методов для осуществления операций над строками Для работы с данным классом строк необходимо подключить заголовочный файл
Пример #include
Вектор std: : vector Контейнер для хранения динамического массива элементов произвольного типа Как и строка, вектор автоматизирует процесс управления памятью, занимаемой элементами массива Везде, где возможно, рекомендуется использовать класс vector как альтернативу динамическому выделению массивов объектов при помощи оператора new К элементам массива предоставляется индексированный доступ Для использования данного класса необходимо подключить заголовочный файл
Пример #include
Двусвязный список std: : list Реализовывает двусвязный список элементов произвольного типа К элементам списка осуществляется последовательный доступ при помощи итераторов Вставка и удаление элементов из произвольного места списка осуществляется за постоянное время Для начала работы с данным контейнером необходимо подключить заголовочный файл
Пример #include #include
Двусторонняя очередь std: : deque Аналогична вектору, но обеспечивает эффективную вставку и удаление элементов не только в конце, но и в начале очереди Для использования необходимо подключить заголовочный файл
Классы std: : map и std: : multimap Ассоциативный контейнер, хранящий пары «ключ» - «значение» Позволяет отображать элементы одного типа в элементы другого или того же самого типа map – все ключи уникальные multimap – допускается дублирование ключей Для подключения данных классов необходимо подключить заголовочный файл
Пример #include
Классы множеств std: : set и std: : multiset Ассоциативный контейнер, хранящий множество элементов определенного типа set – дублирование элементов не допускается multiset – дублирование элементов допускается Для использования данных классов необходимо подключить заголовочный файл
Пример #include
Итераторы Итератор – объект, позволяющий программисту осуществлять перебор элементов контейнера вне зависимости от деталей его реализации Например, осуществлять вставку диапазона элементов одного контейнера в другой Итераторы используются в STL для доступа к элементам контейнеров Обобщенные реализации алгоритмов используют итераторы для обработки элементов контейнеров Итератор – связующее звено между контейнером и алгоритмом
Алгоритмы Обобщенных функции, реализующие типичные алгоритмы над элементами контейнеров Сортировка, поиск, поэлементная обработка Алгоритмы в STL не работают с контейнерами напрямую Вместо этого алгоритмы используют итераторы, задающие определенные элементы или диапазоны элементов контейнера Для работы с алгоритмами STL необходимо подключить заголовочный файл
Пример #include