- •Лекция 1 Динамическая память и интеллектуальные указатели.
- •Лекция 2
- •Лекция 3
- •Исчерпание памяти
- •Лекция 4 Smart-pointer для обработки исключений
- •Создание собственного кода удаления
- •Класс unique_ptr
- •Класс weak_ptr
- •Использование динамических массивов
- •Смарт поинтеры и динамические массивы
- •Класс allocator
- •Тема 2. Обработка исключительных ситуаций
- •Лекция 7
- •Класс Exception
- •Лекция 8
- •Потоки, буферы и файл iostream
- •Перегруженная операция вставки
- •Лекция 9
- •Ввод с помощью cin
- •Тема 4. Файловый ввод/вывод
- •Лекция 10
- •Режимы открытия файла
- •Бинарные файлы
- •Лекция 11
- •Тема 5. Библиотека шаблонов Standart Template Library (stl)
- •Шаблонный класс Vector
- •Лекция 12
- •Цикл for , основанный на диапазоне
- •Обобщённое программирование
- •Лекция 13
- •Виды итераторов
- •Входные итераторы
- •Однонаправленные итераторы
- •Двунаправленные итераторы
- •Произвольного доступа
- •Лекция 14 Двунаправленные итераторы
- •Виды контейнеров
- •Лекция 15 Разработка с использованием Java-платформы
- •Этапы развития языка Java
- •Байт-код
- •Особенности языка Java
- •Программная платформа и виртуальная машина Java
- •Особенности разработки и исполнения объектно-ориентированных приложений на Java Сборка мусора в Java
- •Пакет jdk
- •Ide для работы на Java
- •Особенности настройки работы платформы Java
- •Запуск приложения на языке Java без ide
- •Особенности лексики Java
- •Примитивные типы данных Java
- •Переменные
- •Объявление переменной
- •Область и срок действия переменной
- •Преобразование и приведение типов. Автоматическое приведение и продвижение типов в выражениях. Логические выражения. Арифметические операции
- •Логические операции
- •Предшествование операций
- •Управляющие операторы
- •Операторы выбора Условный оператор if
- •Операторы цикла
- •Разновидность цикла for в стиле for each
- •Применение оператора instanceof
- •Принципы ооп
Лекция 3
Переменные определенные вне тела функции инициализируются нулем. Инициализированные внутри функции переменные встроенного типа остаются не проинициализированными. Попытка копирования или получения значения (доступа) являются ошибкой.
Инициализацию объекта типа класса контролирует класс. Это определяется в конструкторе класса. Большинство встроенных классов позволяет определять объекты без явных инициализаторов. Однако некоторые классы требуют явной инициализации объекта (иначе ошибка компиляции).
По умолчанию создаваемые в динамической памяти объекты инициализируются по умолчанию. Т.е. у локальных объектов встроенного типа будет не валидное значение, а объекты типа класса будут инициализированы конструктором по умолчанию.
Для типов классов, определяющих собственные конструкторы запрос инициализации значением по умолчанию не имеет последствий, т.к. объект инициализируется конструктором класса (стандартным).
Различие существенно в случае встроенных типов:
Инициализация объектов значением по умолчанию присваивает ему конкретное значение, а инициализация по умолчанию – нет. Когда предоставляется инициализатор в круглых скобках для вывода объекта, который предстоит зарезервировать можно использовать ключевое слово auto, но только с одиночным инициализатором в круглых скобках.
Для резервирования константных объектов можно использовать оператор new. Подобно любым константным объектам, динамически созданный константный объект необходимо проинициализировать. Это можно сделать неявно (при наличии конструктора по умолчанию).
Исчерпание памяти
Как только программа использует всю доступную ей память выражения с new будут терпеть неудачу. Если new не способен зарезервировать требуемый объем, он передает исключение типа BadAlloc.
Выражение оператора new позволяет передать дополнительные аргументы. Первый – количество, второй – значение. nothrow указывает, что оператор не должен передавать исключения. Если эта форма оператора new не способна зарезервировать нужный объем, то возвращает нулевой указатель.
Чтобы предотвратить исчерпание памяти при завершении ее использования следует использовать оператор delete, который удаляет объект на который указывает указатель и освобождает область памяти. Передаваемый указатель может быть создан или с new, или быть нулевым. Результат удаления объекта, зарезервированного не оператором new непредсказуем.
Обычный компилятор не способен вычислить, указывает ли указатель на статический объект или на динамический. Подобно любым динамическим объектам, константный динамический объект нужно освобождать вызовом delete. Управляемая указателем shared_ptr память освобождается автоматически с использованием delete при удалении последнего указателя типа shared_ptr.
Динамическая память, управляемая с помощью встроенных, а не интеллектуальных указателей существует пока не будет освобождена явно.
3 проблемы new-delete:
- память забыли освободить
- объект использован после удаления
- повторное освобождение одной и той же памяти
После использования delete указатель становится недопустимым. Но он продолжает держать в себе адрес уже освобожденной памяти. Проблему можно избежать, освободив связанную с ним память непосредственно перед выходом из области видимости этого указателя. После применения delete указателю можно присвоить null_ptr, говорящее о том, что указатель не указывает на объект.
Если не инициализировать интеллектуальный указатель, то он инициализируется как нулевой. Smart-pointer можно инициализировать указателем, возвращенным оператором new. Конструкции smart-pointera, получающие параметры, являются явными, значит нельзя неявно преобразовать встроенный указатель в интеллектуальный. Для этого необходимо использовать явную форму инициализации.
Функция, возвращающая указатель типа shared_ptr не может неявно преобразовать простой указатель в своем операторе return.
По умолчанию, указатель, используемый для инициализации smart-pointera, должен указывать на область динамической памяти, поскольку используют оператор delete для освобождения связанного с ними объекта. Вместо оператора delete можно передать собственную функцию освобождения ресурсов. Рекомендуется использовать функцию make_shared для создания shared_ptr, а не new, т.к. эта функция корректно создает копию указателя.
Не стоит использовать встроенный указатель для обращения к smart-pointer, потому что нельзя быть уверенным, что объект еще не удален.
Метод reset() модифицирует счетчик ссылок, а если достиг нуля – удаляет объект. Его целесообразно использовать с методом unique() для контроля совместного использования объекта несколькими указателями.
3 мар 2021