What's really going on here? I thought you weren't able/supposed to copy unique_ptr's however the following code compiles and runs properly:
std::unique_ptr<SomeObject> CreateObject()
{
return std::unique_ptr<SomeObject>(new SomeObject);
}
// Useage
auto MySomeObject = CreateObject();
Is the unique_ptr's move method being invoked? If so, is there a way to actually create the unique_ptr inside the function and return it without the object getting destroyed when the function scope exits?
I would rather not return the actual pointer then turn it into a unique_ptr as to force usage of unique_ptrs for objects returned by this function. Nor would I want to use shared_ptr's only to avoid the issue proposed in this question.
This is a very performance critical area of the application and I'm afraid extra overhead may be created here.
1 Answer 1
I thought you weren't able/supposed to copy unique_ptr's
Indeed you can't. But you can move them, transferring ownership of the managed object from one smart pointer to another.
Is the unique_ptr's move method being invoked?
Yes. A function's return value is moved if possible; and assignment from the temporary return value is also done by moving.
is there a way to actually create the
unique_ptrinside the function and return it without the object getting destroyed when the function scope exits?
Yes, that's exactly what's happening here. Moving a unique_ptr transfers ownership of the managed object; so here, ownership is moved from the temporary value of return expression, to the return value, to MySomeObject. (In practice, the first move will be elided; but the effect is the same).
This is a very performance critical area of the application and I'm afraid extra overhead may be created here.
The extra overhead of moving a unique_ptr versus copying a raw pointer is:
- nulling the pointer when it's moved from;
- checking whether to delete an object when the pointer is destroyed.
It's unlikely that either of these will be significant, especially when compared with the cost of new.
unique_ptr, it's moving it. The object is therefore not destroyed untilMySomeObjectis destroyed. Also, I'd be surprised if the above yields any overhead at all, since the RVO will very likely make sure thatMySomeObjectis initialized directly without calling any move-ctor.CreateObjectis part of C++14 and calledstd::make_unique.