Когда заменить глобальный std:: unique_ptr на singleton
Сотрудник настаивал на использовании Meyer Singleton для всех глобальных переменных указателя, поскольку "нет гарантии, что построение глобального unique_ptr
не будет выбрасывать". Поэтому вместо:
#include <memory>
std::unique_ptr<Foo> ptr(nullptr); // Apparently this isn't safe.
int main(/*blah*/)
{
ptr.reset(new Foo());
}
Теперь имеем
unique_ptr<Foo> singleton
{
try
{
static unique_ptr<Foo> ptr();
return ptr;
}
catch (...)
{
std::cerr << "Failed to create single instance\n";
exit(1);
}
return unique_ptr<Type>();
}
int main()
{
}
Для меня это похоже на решение проблемы. У него есть точка?
Ответы
Ответ 1
Ваш коллега неверен (или, может быть, просто устарел, пред-стандартные версии unique_ptr
могут отличаться). Конструктор nullptr_t
unique_ptr
гарантированно не бросает (20.7.1.2):
constexpr unique_ptr (nullptr_t) noexcept : unique_ptr() {}
Так как он также constexpr
(и поскольку nullptr
является константным выражением), его необходимо инициализировать во время постоянной инициализации (3.6.2/2). Таким образом, управление порядком инициализации (другая причина, по которой может быть полезна однопользовательская система Meyers) также не применяется.
Ответ 2
"нет гарантии, что построение глобального unique_ptr не будет выбрасывать"
И если он бросает, что происходит? Приложение прекращается, хотя в стандарте не указывается, если стек разматывается, если вы не поймаете исключение (в качестве глобальной переменной нет места для исключения исключения). Я не совсем понимаю, как предлагаемое решение является явным улучшением.