As std::unique_ptr
provides a handy way to avoid memory leaks and ensure exception safety, it is sensible to pass them around rather than raw pointers. Thus, one may want (member) functions with a signature like
std::unique_ptr<some_type> foo(some data);
Unfortunately, when implementing such a function, one cannot simply
std::unique_ptr<some_type> foo(some data)
{
return { new some_type(data) }; // error
}
but must instead
std::unique_ptr<some_type> foo(some data)
{
return std::move( std::unique_ptr<some_type>( new some_type(data) ) ); // awkward
}
because the constructor unique_ptr::unique_ptr(pointer)
is explicit
. What is the reasoning behind this constructor being explicit
?
One motivation to make constructors explicit
is to guard against unintended implicit type conversion. However, as unique_ptr
cannot be passed by value, this should not really be a problem, should it?
std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.
The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from a function.
unique_ptr is not copyable, it is only moveable. This will directly affect Test, which is, in your second, example also only moveable and not copyable.
unique_ptr<> is one of the Smart pointer implementation provided by c++11 to prevent memory leaks. A unique_ptr object wraps around a raw pointer and its responsible for its lifetime. When this object is destructed then in its destructor it deletes the associated raw pointer.
unique_ptr
takes ownership of passed pointer. Taking ownership should be explicit - you don't want some pointer to 'magically' become owned (and deleted) by some class (that was one of issues with deprecated std::auto_ptr
).
for example:
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's explicit and error is clearly visible
please note, that std::move
is not required in return
statement (special language exception - local variables as return
arguments can be treated as 'moved').
Also - in C++14 you can use std::make_unique
to make it less awkward:
return std::make_unique<some_data>(some_data_argument1, arg2);
(it can be also easily added to C++11 - read here)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With