silent_coder silent_coder - 1 month ago 10
C++ Question

Constructor dependency injection: unique_ptr + move vs shared_ptr

Let's assume we have something like this:

struct Complex{
Complex(Part1 p1, Part2 p2, Part3 p3)
}

Part1 p1;
Part2 p2;
Part3 p3;


However passing copies is not effective, so we need to move to pointers. The questions is what type to use —
unique_ptr
or
shared_ptr


At first glance, since
Complex
is a real owner of
p1, p2, p3
, it seems
unique_ptr
is better; however, since it could not be copied, we would need to use
std::move
.

So my question is — what is the better way for this case, create
unqiue_ptr
out of
Part
, and then use
move
in
Complex
's constructor, or create
shared_ptr
from the beggining and use
shared_ptr
instead?

Answer

The best solution would be to make the Part types cheap to move, and move them in. However, if that is not an option, you will have to resort to managing them dynamically.

As you say, Complex owns the parts, so it should accept them as std::uniqe_ptr<Part> and move these pointers into itself. Moving a std::unique_ptr is dirt cheap: it probably involes just two pointer assignments.

On the other hand, using std::shared_ptr and copying that involves an unnecessary atomic increment (for creating the copy) and decrement (for destroying the original). Atomic operations are certainly far from cheap for today's cache-heavy, multi-core processors.

So just stick to the intended semantics of your code (unique ownership, which is idiomatically expressed by std::unique_ptr), and you will get good performance as a bonus.

Comments