Есть ли у 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_unique
в основном двукратна:
make_unique
безопасен для создания временных рядов, тогда как при явном использовании new
вам нужно запомнить правило о том, что вы не используете неназванные временные файлы.
foo(make_unique<T>(), make_unique<U>()); // exception safe
foo(unique_ptr<T>(new T()), unique_ptr<U>(new U())); // unsafe*
Наконец, добавление make_unique
означает, что люди могут "никогда" использовать new
, а не предыдущее правило, "никогда не использовать new
, кроме случаев, когда вы делаете unique_ptr
".
Также есть и третья причина:
make_unique
не требует использования избыточного типа. unique_ptr<T>(new T())
→ make_unique<T>()
Ни одна из причин не связана с повышением эффективности выполнения, как это делает использование make_shared
(из-за избежания второго выделения за счет потенциально более высокой пиковой загрузки памяти).
* Ожидается, что С++ 17 будет включать изменение правила, что означает, что это уже небезопасно. См. Документы комитета С++ P0400R0 и P0145R3.
std::make_unique
и std::make_shared
существуют по двум причинам:
std::unique_ptr
или std::shared_ptr
. (Смотрите раздел "Примечания" здесь.)Это не совсем о производительности во время выполнения. Существует бит о контрольном блоке, а T
выделяется все сразу, но я думаю, что больше бонусов и меньше мотивации для существования этих функций.
Причина, по которой вам нужно будет использовать std::unique_ptr(new A())
или std::shared_ptr(new A())
непосредственно вместо std::make_*()
, не сможет получить доступ к конструктору класса A
вне текущей области.