Скачиваний:
62
Добавлен:
05.07.2021
Размер:
94.13 Кб
Скачать

Лекция 4 Smart-pointer для обработки исключений

Приложения использующие обработку исключений для продолжения работы программы после исключения должны иметь способы правильного освобождения ресурсов в случае возникновения исключения.

Использование smartpointer ов при освобождении дин памяти элемента , когда она больше не нужна, даже при преждевременном выходе из блока в связи с возникновением исключением.

При выходе из функции обычно или в связи с исключением удаляются все её локальные объекты. Если для управления памяти используется встроенные(или обычные) указатели, исключение происходит после оператора new, но перед оператором delete, то контролируемая память не освобождается.

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

Создание собственного кода удаления

По умолчанию указатели shared_ptr подразумевали , что они указывают на динамическую память, вызванную с помощью оператора new. Следовательно, когда указатель shared_ptr удаляется должен быть вызван по умолчанию оператор delete. Чтобы использовать указатель shared_ptr для освобождения других типов ресурсов, следует определить функцию, используемую вместо оператора delete. То есть при создании указателя типа shared_ptr можно передать не обязательные аргументы, указывающие на функцию удаления.

Интеллектуальные указатели могут обеспечить безопасность и удобство работы с динамической памятью, только при выполнении ряда условий:

  • Не используйте значения одного и того встроенного указателя для инициализации или переустановки нескольких смарт поинтеров.

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

Класс unique_ptr

Указатель unique_ptr единолично владеет объектом на которой он указывает, в отличие от shared_ptr, только один указатель типа unique_ptr может одновременно указывать на ресурс, который будет удаляться при удалении указателя unique_ptr.

Функция make_unique() позволяет создать указатель unique_ptr, который может быть связан с областью памятью, возращенной оператором new.

Поскольку unique_ptr единолично владеет объектом, то он не поддерживает обычного копирования или присваивания. Указатель unique_ptr нельзя ни присвоить, ни скопировать, но можно передать собственность от одного указателя unique_ptr к другому, вызвав функцию release() или reset(). Метод release() возвращает указатель, хранимый в настоящее время в указателе unique_ptr, и обнуляет unique_ptr, к которому применяется. Метод reset() может получать необязательный указатель и переустанавливать указатель unique_ptr на заданный. Если указатель unique_ptr не нулевой , то объект, на который он указывает удаляется. Вызов функции release() нарушает связь между указателем unique_ptr и объект.

Часто функцией release() можно пользоваться для инициализации или присваивания его значения другому указателю, но если другой смарт поинтер не используется для хранения указателя, возвращенного функцией release(), то ответственность за освобождение этого ресурса берут на себя программист. Функция release() не возвращает смарт поинтер, а возвращает просто поинтер.

Из правила, запрещающего копирования указателя unique_ptr есть исключения:

  • Можно копировать и присваивать те указатели unique_ptr, которые предстоит удалить.

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

В прежней версии библиотеки С++ использовался класс auto_ptr, обладавший некоторыми свойствами указателя unique_ptr. В частности, невозможно было хранить указатели типа auto_ptr в контейнере и возвращать из функции.

Подобно указателю shared_ptr, для освобождения объекта, на который указывает unique_ptr, по умолчанию используется оператор delete. Тип функции удаления можно предоставить в угловых скобках на ряду с типом, на который может указывать unique_ptr. Для определения типа указателя на функцию используется ключевое слово decltype, позволяющее создавать тип функции.