Глава №15. Итоговый тест

  Юрий  | 

  Обновл. 2 Июл 2019  | 

 2507

 ǀ   1 

Ещё одна глава позади. Последний итоговый тест. Пора закрепить пройденный материал.

Теория

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

Семантика копирования позволяет копировать классы с помощью конструктора копирования и оператора присваивания копированием.

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

std::auto_ptr устарел и его следует избегать.

Ссылка r-value — это ссылка, которая инициализируется значениями r-values. Ссылка r-value создаётся с использованием двойного амперсанда. Помните, что писать функции, которые принимают в качестве параметров ссылки r-value — хорошо, но возвращать ссылки r-value — плохо.

Если мы создаём объект или выполняем операцию присваивания, где аргументом является l-value, то единственное разумное, что мы можем сделать — это скопировать l-value. Дело в том, что не всегда безопасно изменять l-value, так как оно ещё может быть использовано позже в программе. Если у нас есть выражение a = b, то мы предполагаем, что b не будет каким-либо образом изменен позже.

Однако, если мы создаём объект или выполняем операцию присваивания, где аргументом является r-value, то мы знаем, что r-value — это всего лишь временный объект. Вместо того, чтобы копировать его (что может быть затратно), мы можем просто переместить его ресурсы (что не очень затратно) в объект, который создаём или которому присваиваем. Это безопасно, поскольку временный объект в любом случае будет уничтожен в конце выражения, и мы можем быть уверены, что он больше никогда не будет использован снова!

Вы можете использовать ключевое слово delete для отключения семантики копирования в создаваемых классах, удалив конструктор копирования и оператор присваивания копированием.

std::move() позволяет конвертировать l-value в r-value. Это полезно, когда вы хотите использовать семантику перемещения вместо семантики копирования с аргументом, который изначально является l-value.

std::unique_ptr — это класс умного указателя (или просто «умный указатель»), который единолично владеет переданным ему динамически выделенным ресурсом. std::make_unique() — это функция, добавленная в C++14, которую вы должны использовать для создания нового std::unique_ptr. В std::unique_ptr семантика копирования по умолчанию отключена.

std::shared_ptr — это класс умного указателя, который следует использовать, когда нужно, чтобы одним динамически выделенным ресурсом владели сразу несколько умных указателей. Ресурс не будет уничтожен до тех пор, пока не будет уничтожен последний управляющий им std::shared_ptr. Для создания нового std::shared_ptr предпочтительнее использовать функцию std::make_shared(). Для создания дополнительного std::shared_ptr, который бы указывал на текущий ресурс, вы должны использовать семантику копирования.

std::weak_ptr — это класс умного указателя, который вы должны использовать, когда вам нужен один или несколько указателей с возможностью просмотра и доступа к динамически выделенному ресурсу, которым управляет другой std::shared_ptr, но, чтобы этот указатель не участвовал в уничтожении ресурса. std::weak_ptr владельцем ресурса не считается.

Тест


Задание №1

Объясните, когда следует использовать следующие типы указателей:

a) std::unique_ptr

Ответ 1.a)

std::unique_ptr следует использовать, когда нужно, чтобы умный указатель единолично владел динамически выделенным ресурсом.

b) std::shared_ptr

Ответ 1.b)

std::shared_ptr следует использовать, когда нужно, чтобы сразу несколько умных указателей владело одним динамически выделенным ресурсом. Ресурс не будет уничтожен до тех пор, пока не будут уничтожены все std::shared_ptr, владеющие им.

c) std::weak_ptr

Ответ 1.c)

std::weak_ptr следует использовать, когда нужно иметь доступ к ресурсу, которым управляет другой std::shared_ptr, но не нужно, чтобы продолжительность жизни std::shared_ptr была привязана к продолжительности жизни std::weak_ptr.

d) std::auto_ptr

Ответ 1.d)

std::auto_ptr устарел и его следует избегать.

Задание №2

Объясните, как ссылки r-value замешаны в реализации семантики перемещения.

Ответ №2

Поскольку значения r-values являются временными, то мы знаем, что они будут уничтожены сразу же после их использования. При передаче или возврате r-value по значению расточительнее будет выполнять копирование, а затем уничтожать оригинал. Вместо этого гораздо эффективнее будет просто переместить (украсть) ресурсы r-value в нужный объект.

Задание №3

Что не так со следующими программами? Обновите их в соответствие с рекомендациями, полученными в этой главе.

a)

Ответ 3.a)

ptr2 был создан из item-а вместо ptr1. Это означает, что теперь у нас есть два отдельных std::shared_ptr, каждый из которых пытается независимо управлять Item-ом (они не знают о существовании друг друга). Когда один из этих умных указателей выйдет из области видимости, то другой останется висячим указателем.

ptr2 должен быть скопирован из ptr1 и для создания std::shared_ptr следует использовать функцию std::make_shared():

b)

Ответ 3.b)

Если конструктор класса Something выбросит исключение, то один из объектов класса Something, вполне вероятно, не будет уничтожен должным образом.

Решение заключается в использовании std::make_shared():

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (18 оценок, среднее: 4,78 из 5)
Загрузка...

Комментариев: 1

  1. Аватар osoznanie:

    Не хватает, конечно, тестов практических)
    От теории немного голова болит)
    Спасибо за перевод!

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *