Какова аргументация конструктора std:: unique_ptr <T> из T *, являющегося явной?
Как std::unique_ptr
обеспечивает удобный способ избежать утечек памяти и обеспечения безопасности исключений, разумно передавать их, а не сырые указатели. Таким образом, можно хотеть (член) функции с сигнатурой типа
std::unique_ptr<some_type> foo(some data);
К сожалению, при реализации такой функции нельзя просто
std::unique_ptr<some_type> foo(some data)
{
return { new some_type(data) }; // error
}
но вместо этого нужно
std::unique_ptr<some_type> foo(some data)
{
return std::move( std::unique_ptr<some_type>( new some_type(data) ) ); // awkward
}
потому что конструктор unique_ptr::unique_ptr(pointer)
равен explicit
. Какова причина этого конструктора: explicit
?
Одна мотивация создания конструкторов explicit
заключается в защите от непреднамеренного неявного преобразования типа. Однако, поскольку unique_ptr
не может быть передано по значению, это не должно быть проблемой, не так ли?
Ответы
Ответ 1
unique_ptr
переходит в собственность переданного указателя. Принятие права собственности должно быть явным - вы не хотите, чтобы какой-либо указатель на "магически" становился владельцем (и удалялся) каким-то классом (это была одна из проблем с устаревшим std::auto_ptr
).
например:
void fun(std::unique_ptr<X> a) { .... }
X x;
fun(&x); // BOOM, deleting object on stack, fortunately it does not compile
fun(std::unique_ptr<X>(&x)); // compiles, but it explicit and error is clearly visible
обратите внимание, что std::move
не требуется в выражении return
(специальное исключение языка - локальные переменные как аргументы return
могут рассматриваться как "перемещены" ).
Также - в С++ 14 вы можете использовать std::make_unique
, чтобы сделать его менее неудобным:
return std::make_unique<some_data>(some_data_argument1, arg2);
(его также можно легко добавить в С++ 11 - прочитайте здесь)
Ответ 2
Аргументы, принимающие уникальный ptr, не должны молча владеть указателями.
Таким образом, ctor явно.
Чтобы вернуться, попробуйте make_unique<foo>(?)
вместо {new foo(?)}
.