Есть ли std::make_unique
какие-то преимущества эффективности std::make_shared
?
По сравнению с ручным строительством std::unique_ptr
:
std::make_unique<int>(1); // vs
std::unique_ptr<int>(new int(1));
Есть ли std::make_unique
какие-то преимущества эффективности std::make_shared
?
По сравнению с ручным строительством std::unique_ptr
:
std::make_unique<int>(1); // vs
std::unique_ptr<int>(new int(1));
make_shared
какая-то эффективность по сравнению с простым написанием длинного кода?make_shared
может выделить как пространство для объекта, так и пространство для блока управления вместе в одном распределении. Цена этого заключается в том, что объект не может быть освобожден отдельно от блока управления, поэтому, если вы используетеweak_ptr
много, вы можете использовать больше памяти.Ответы:
За этим стоит
make_unique
в первую очередь двоякая мотивация :make_unique
безопасен для создания временных файлов, тогда как при явном использованииnew
вы должны помнить правило о запрете использования безымянных временных файлов.Добавление
make_unique
finally означает, что мы можем сказать людям «никогда»,new
а не предыдущее правило «никогда» использовать,new
кроме случаев, когда вы делаетеunique_ptr
».Есть и третья причина:
make_unique
не требует использования избыточного типа.unique_ptr<T>(new T())
->make_unique<T>()
Ни одна из причин не связана с повышением эффективности времени выполнения, как это
make_shared
делается при использовании (из-за избежания второго выделения за счет потенциально более высокого пикового использования памяти).* Ожидается, что C ++ 17 будет включать изменение правила, которое означает, что это больше не небезопасно. См. Документы комитета C ++ P0400R0 и P0145R3 .
источник
std::unique_ptr
и то,std::shared_ptr
почему мы можем сказать людям , чтобы «никогда не использоватьnew
.»make_shared
иmake_unique
последняя часть, которой раньше не хватало.f
:f(unique_ptr<T>(new T), function_that_can_throw());
- процитировать ответ: Компилятор разрешено вызова (в порядке убывания):new T
,function_that_can_throw()
,unique_ptr<T>(...)
, Очевидно, если наfunction_that_can_throw
самом деле бросает, то вы протекаете.make_unique
предотвращает этот случай. Итак, на мой вопрос дан ответ.std::make_unique
иstd::make_shared
существуют по двум причинам:std::unique_ptr
илиstd::shared_ptr
. (См. Раздел «Примечания» здесь .)Дело не в эффективности времени выполнения. Есть кое-что о блоке управления и
T
выделении всех сразу, но я думаю, что это скорее бонус, а не мотивация для существования этих функций.источник
std::make_shared
гарантирует, что хотя бы один из них будет заключен в интеллектуальный указатель до того, как произойдет выделение другой памяти, следовательно, никаких утечек.Причина, по которой вам придется использовать
std::unique_ptr(new A())
илиstd::shared_ptr(new A())
напрямую, вместоstd::make_*()
невозможности получить доступ к конструктору классаA
за пределами текущей области.источник
Рассмотрим вызов функции
Предположим, что new выполняется
A()
успешно, но newB()
вызывает исключение: вы перехватываете его, чтобы возобновить нормальное выполнение вашей программы. К сожалению, стандарт C ++ не требует, чтобы объект A был уничтожен, а его память освобождена: утечка памяти происходит незаметно, и ее невозможно очистить. Обернув A и B,std::make_uniques
вы уверены, что утечки не произойдет:Дело в том, что
std::make_unique<A>
иstd::make_unique<B>
теперь являются временными объектами, и очистка временных объектов правильно указана в стандарте C ++: их деструкторы будут запущены, а память будет освобождена. Поэтому, если вы можете, всегда предпочитайте выделять объекты с помощьюstd::make_unique
иstd::make_shared
.источник